ListView 数据在滚动时被清除
ListView Data got cleared on scrolling
我正在开发一个显示 listView
和 checkBoxes
的应用程序。
当我滚动 listView
时,CheckBoxes
的值被清除。
下面是我的代码
适配器class:
public class Conference_listViewAdapter extends BaseAdapter {
Activity context;
LayoutInflater inflater;
public static List<Model> data = null;
ArrayList<String> id_list = new ArrayList<String>();
ViewHolder holder;
int pos;
public Conference_listViewAdapter(Activity context,List<Model> list, ArrayList<String> id_list) {
data = list;
this.id_list = id_list;
this.context = context;
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return data.get(position).getName();
}
@Override
public long getItemId(int position) {
return Long.valueOf(id_list.get(position));
}
public View getView(final int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
LayoutInflater inflator = context.getLayoutInflater();
view = inflator.inflate(R.layout.people_list_item1, null);
holder = new ViewHolder();
holder.title = (TextView) view.findViewById(R.id.tv_name);
holder.image = (ImageView) view.findViewById(R.id.avtaar);
holder.favorite = (CheckBox) view.findViewById(R.id.fav);
holder.favorite.setTag(position);
view.setTag(holder);
holder.favorite.setTag(data.get(position));
} else {
view = convertView;
((ViewHolder) view.getTag()).favorite.setTag(data.get(position));
}
holder.favorite.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Model element = (Model) holder.favorite.getTag();
element.setSelected(buttonView.isChecked());
//notifyDataSetChanged();
}
});
ViewHolder holder = (ViewHolder) view.getTag();
holder.favorite.setChecked(data.get(position).isSelected());
holder.title.setText(data.get(position).getName());
try {
holder.image.setImageBitmap(openPhoto(Long.valueOf(id_list.get(position))));
} catch (Exception e) {
e.printStackTrace();
}
return view;
}
class ViewHolder {
TextView title;
TextView model;
ImageView image;
CheckBox favorite;
}
}
数据模型class
public class Model {
private String name;
private boolean selected;
public Model(String name) {
this.name = name;
selected = false;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
}
不知道哪里做错了
改变这个..
@Override
public Object getItem(int position) {
return position;
}
到..
@Override
public Object getItem(int position) {
return data.get(position);
}
更新:
试试这个..
public View getView(final int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
LayoutInflater inflator = context.getLayoutInflater();
view = inflator.inflate(R.layout.people_list_item1, null);
holder = new ViewHolder();
holder.title = (TextView) view.findViewById(R.id.tv_name);
holder.image = (ImageView) view.findViewById(R.id.avtaar);
holder.favorite = (CheckBox) view.findViewById(R.id.fav);
holder.favorite.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//do what you want..
}
});
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.favorite.setChecked(data.get(position).isSelected());
holder.title.setText(data.get(position).getName());
try {
holder.image.setImageBitmap(openPhoto(Long.valueOf(id_list.get(position))));
} catch (Exception e) {
e.printStackTrace();
}
return view;
}
在类似的情况下,比如带有复选框、单选按钮、计数框等的列表视图,我通常按如下方式操作
1)保留一个大小类似于列表视图(行数)的数组列表
2) 这个 array/arraylist 将在适配器 class 的构造函数中初始化,所有位置都为零
3) 在声明复选框并将其标签设置为 position
之后在 getView() 中
public class Conference_listViewAdapter extends BaseAdapter {
Activity context;
LayoutInflater inflater;
public static List<Model> data = null;
ArrayList<String> id_list = new ArrayList<String>();
ArrayList<String> myarray=new java.util.ArrayList<String>();
ViewHolder holder;
int pos;
public Conference_listViewAdapter(Activity context,List<Model> list, ArrayList<String> id_list) {
data = list;
this.id_list = id_list;
this.context = context;
for(int i=0;i<id_list.size();i++)
myarray.add("0");
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
LayoutInflater inflator = context.getLayoutInflater();
view = inflator.inflate(R.layout.people_list_item1, null);
holder = new ViewHolder();
holder.title = (TextView) view.findViewById(R.id.tv_name);
holder.image = (ImageView) view.findViewById(R.id.avtaar);
holder.favorite = (CheckBox) view.findViewById(R.id.fav);
holder.favorite.setTag(position);
view.setTag(holder);
if(myarray.get(Integer.parseInt(holder.favorite.getTag().toString()).equalsIgnoreCase("1")
//make your checkbox checked
else
//keep checkbox unchecked
holder.favorite.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if( isChecked) myarray.set(Integer.parseInt(holder.favorite.getTag().toString()),"1");
else
myarray.set(Integer.parseInt(holder.favorite.getTag().toString()),"0");
notifydatasetchanged();
});
holder.favorite.setTag(data.get(position));
} else {
view = convertView;
((ViewHolder) view.getTag()).favorite.setTag(data.get(position));
}
ViewHolder holder = (ViewHolder) view.getTag();
holder.favorite.setChecked(data.get(position).isSelected());
holder.title.setText(data.get(position).getName());
try {
holder.image.setImageBitmap(openPhoto(Long.valueOf(id_list.get(position))));
} catch (Exception e) {
e.printStackTrace();
}
return view;
}
class ViewHolder {
TextView title;
TextView model;
ImageView image;
CheckBox favorite;
Boolean selected;
}
}
总是这样可以解决我的列表视图滚动问题..
我认为这是一个常见的错误。您需要设置此代码
holder.favorite.setOnCheckedChangeListener(new OnCheckedChangeListener()
在 if/else 块之外。原因是无论convertView是否=null,都要设置监听器。我知道您的代码可能需要一些安排,但我认为您可以比我做得更好,因为我的代码风格不同。这够清楚了吗?
另一个可能的错误是 holder.favorite.setTag(position)
。原因是您的侦听器中的代码 Model element = (Model) holder.favorite.getTag()
。您正在保存 int position
并将其类型转换为 Model
class,无法工作。更改覆盖getItem,先编码再做。示例代码总结:
@Override
public Object getItem(int position) {
return data.get(position); // return the Model
}
...
holder.favorite.setTag( getItem(position) );
注意:再次 holder.favorite.setTag 应设置在 之外 if/else 块。只有 view.setTag(holder) 可以在 if 块中设置,因为它是一个新的视图对象。
除此之外,我认为您的代码设计应该可行!
Suggested code changes...
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null; // different
if (convertView == null) {
...
holder.favorite.setTag(data.get(position)); // different
view.setTag(holder); // different
}
else {
view = convertView;
holder = (ViewHolder) view.getTag(); // different
}
...
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Model element = (Model) buttonView.getTag(); // different
变化是:
- 我使用不同的注释来强调代码的变化。
ViewHolder holder
在 getView
() 中声明。删除 class 内顶部的 holder 声明。我认为这是更好的编码风格,因为 holder 更接近于找到您正在使用它的位置,使其在 getView 本地。
holder.favorite.setTag
和view.setTag
的位置调换了。我认为这是一种 更安全 的编码风格。我认为在将持有人用作对象视图的参数之前先设置持有人更安全。这可能并不重要,我承认。
view.getTag
当 convertView 不是 = null 时是必需的。当您在同一块中设置带有 view.getTag()).favorite.setTag
的标签时,您实际上是在以意外行为更改持有人的内容。
- 在代码
(Model) buttonView.getTag()
中,使用了 buttonView 而不是 holder.favorite。我希望这会得到正确的模型对象。
您必须保存 ViewHolder
的状态。然后在convertView == null
时设置tag
,在else
条件下得到
看看我是怎么做的:
public class Conference_listViewAdapter extends ArrayAdapter<Model> {
Activity context;
LayoutInflater inflater;
public static List<Model> data = null;
ArrayList<String> id_list = new ArrayList<String>();
int pos;
public Conference_listViewAdapter(Activity context, List<Model> list, ArrayList<String> id_list) {
super(context, R.layout.people_list_item1, list);
this.context = context;
this.data = list;
this.id_list = id_list;
}
public View getView(final int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
LayoutInflater inflator = context.getLayoutInflater();
view = inflator.inflate(R.layout.people_list_item1, null);
final ViewHolder holder = new ViewHolder();
holder.title = (TextView) view.findViewById(R.id.tv_name);
holder.image = (ImageView) view.findViewById(R.id.avtaar);
holder.favorite = (CheckBox) view.findViewById(R.id.fav);
view.setTag(holder);
holder.favorite.setTag(data.get(position));
holder.favorite.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Model element = (Model) holder.favorite.getTag();
element.setSelected(buttonView.isChecked());
}
});
} else {
view = convertView;
((ViewHolder) view.getTag()).favorite.setTag(data.get(position));
}
ViewHolder holder = (ViewHolder) view.getTag();
holder.favorite.setChecked(data.get(position).isSelected());
holder.title.setText(data.get(position).getName());
try {
holder.image.setImageBitmap(openPhoto(Long.valueOf(id_list.get(position))));
} catch (Exception e) {
e.printStackTrace();
}
return view;
}
static class ViewHolder {
protected TextView title;
protected CheckBox favorite;
ImageView image;
}
我正在开发一个显示 listView
和 checkBoxes
的应用程序。
当我滚动 listView
时,CheckBoxes
的值被清除。
下面是我的代码
适配器class:
public class Conference_listViewAdapter extends BaseAdapter {
Activity context;
LayoutInflater inflater;
public static List<Model> data = null;
ArrayList<String> id_list = new ArrayList<String>();
ViewHolder holder;
int pos;
public Conference_listViewAdapter(Activity context,List<Model> list, ArrayList<String> id_list) {
data = list;
this.id_list = id_list;
this.context = context;
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return data.get(position).getName();
}
@Override
public long getItemId(int position) {
return Long.valueOf(id_list.get(position));
}
public View getView(final int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
LayoutInflater inflator = context.getLayoutInflater();
view = inflator.inflate(R.layout.people_list_item1, null);
holder = new ViewHolder();
holder.title = (TextView) view.findViewById(R.id.tv_name);
holder.image = (ImageView) view.findViewById(R.id.avtaar);
holder.favorite = (CheckBox) view.findViewById(R.id.fav);
holder.favorite.setTag(position);
view.setTag(holder);
holder.favorite.setTag(data.get(position));
} else {
view = convertView;
((ViewHolder) view.getTag()).favorite.setTag(data.get(position));
}
holder.favorite.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Model element = (Model) holder.favorite.getTag();
element.setSelected(buttonView.isChecked());
//notifyDataSetChanged();
}
});
ViewHolder holder = (ViewHolder) view.getTag();
holder.favorite.setChecked(data.get(position).isSelected());
holder.title.setText(data.get(position).getName());
try {
holder.image.setImageBitmap(openPhoto(Long.valueOf(id_list.get(position))));
} catch (Exception e) {
e.printStackTrace();
}
return view;
}
class ViewHolder {
TextView title;
TextView model;
ImageView image;
CheckBox favorite;
}
}
数据模型class
public class Model {
private String name;
private boolean selected;
public Model(String name) {
this.name = name;
selected = false;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
}
不知道哪里做错了
改变这个..
@Override
public Object getItem(int position) {
return position;
}
到..
@Override
public Object getItem(int position) {
return data.get(position);
}
更新:
试试这个..
public View getView(final int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
LayoutInflater inflator = context.getLayoutInflater();
view = inflator.inflate(R.layout.people_list_item1, null);
holder = new ViewHolder();
holder.title = (TextView) view.findViewById(R.id.tv_name);
holder.image = (ImageView) view.findViewById(R.id.avtaar);
holder.favorite = (CheckBox) view.findViewById(R.id.fav);
holder.favorite.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//do what you want..
}
});
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.favorite.setChecked(data.get(position).isSelected());
holder.title.setText(data.get(position).getName());
try {
holder.image.setImageBitmap(openPhoto(Long.valueOf(id_list.get(position))));
} catch (Exception e) {
e.printStackTrace();
}
return view;
}
在类似的情况下,比如带有复选框、单选按钮、计数框等的列表视图,我通常按如下方式操作 1)保留一个大小类似于列表视图(行数)的数组列表 2) 这个 array/arraylist 将在适配器 class 的构造函数中初始化,所有位置都为零 3) 在声明复选框并将其标签设置为 position
之后在 getView() 中public class Conference_listViewAdapter extends BaseAdapter {
Activity context;
LayoutInflater inflater;
public static List<Model> data = null;
ArrayList<String> id_list = new ArrayList<String>();
ArrayList<String> myarray=new java.util.ArrayList<String>();
ViewHolder holder;
int pos;
public Conference_listViewAdapter(Activity context,List<Model> list, ArrayList<String> id_list) {
data = list;
this.id_list = id_list;
this.context = context;
for(int i=0;i<id_list.size();i++)
myarray.add("0");
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
LayoutInflater inflator = context.getLayoutInflater();
view = inflator.inflate(R.layout.people_list_item1, null);
holder = new ViewHolder();
holder.title = (TextView) view.findViewById(R.id.tv_name);
holder.image = (ImageView) view.findViewById(R.id.avtaar);
holder.favorite = (CheckBox) view.findViewById(R.id.fav);
holder.favorite.setTag(position);
view.setTag(holder);
if(myarray.get(Integer.parseInt(holder.favorite.getTag().toString()).equalsIgnoreCase("1")
//make your checkbox checked
else
//keep checkbox unchecked
holder.favorite.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if( isChecked) myarray.set(Integer.parseInt(holder.favorite.getTag().toString()),"1");
else
myarray.set(Integer.parseInt(holder.favorite.getTag().toString()),"0");
notifydatasetchanged();
});
holder.favorite.setTag(data.get(position));
} else {
view = convertView;
((ViewHolder) view.getTag()).favorite.setTag(data.get(position));
}
ViewHolder holder = (ViewHolder) view.getTag();
holder.favorite.setChecked(data.get(position).isSelected());
holder.title.setText(data.get(position).getName());
try {
holder.image.setImageBitmap(openPhoto(Long.valueOf(id_list.get(position))));
} catch (Exception e) {
e.printStackTrace();
}
return view;
}
class ViewHolder {
TextView title;
TextView model;
ImageView image;
CheckBox favorite;
Boolean selected;
}
}
总是这样可以解决我的列表视图滚动问题..
我认为这是一个常见的错误。您需要设置此代码
holder.favorite.setOnCheckedChangeListener(new OnCheckedChangeListener()
在 if/else 块之外。原因是无论convertView是否=null,都要设置监听器。我知道您的代码可能需要一些安排,但我认为您可以比我做得更好,因为我的代码风格不同。这够清楚了吗?
另一个可能的错误是 holder.favorite.setTag(position)
。原因是您的侦听器中的代码 Model element = (Model) holder.favorite.getTag()
。您正在保存 int position
并将其类型转换为 Model
class,无法工作。更改覆盖getItem,先编码再做。示例代码总结:
@Override
public Object getItem(int position) {
return data.get(position); // return the Model
}
...
holder.favorite.setTag( getItem(position) );
注意:再次 holder.favorite.setTag 应设置在 之外 if/else 块。只有 view.setTag(holder) 可以在 if 块中设置,因为它是一个新的视图对象。
除此之外,我认为您的代码设计应该可行!
Suggested code changes...
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null; // different
if (convertView == null) {
...
holder.favorite.setTag(data.get(position)); // different
view.setTag(holder); // different
}
else {
view = convertView;
holder = (ViewHolder) view.getTag(); // different
}
...
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Model element = (Model) buttonView.getTag(); // different
变化是:
- 我使用不同的注释来强调代码的变化。
ViewHolder holder
在getView
() 中声明。删除 class 内顶部的 holder 声明。我认为这是更好的编码风格,因为 holder 更接近于找到您正在使用它的位置,使其在 getView 本地。holder.favorite.setTag
和view.setTag
的位置调换了。我认为这是一种 更安全 的编码风格。我认为在将持有人用作对象视图的参数之前先设置持有人更安全。这可能并不重要,我承认。view.getTag
当 convertView 不是 = null 时是必需的。当您在同一块中设置带有view.getTag()).favorite.setTag
的标签时,您实际上是在以意外行为更改持有人的内容。- 在代码
(Model) buttonView.getTag()
中,使用了 buttonView 而不是 holder.favorite。我希望这会得到正确的模型对象。
您必须保存 ViewHolder
的状态。然后在convertView == null
时设置tag
,在else
条件下得到
看看我是怎么做的:
public class Conference_listViewAdapter extends ArrayAdapter<Model> {
Activity context;
LayoutInflater inflater;
public static List<Model> data = null;
ArrayList<String> id_list = new ArrayList<String>();
int pos;
public Conference_listViewAdapter(Activity context, List<Model> list, ArrayList<String> id_list) {
super(context, R.layout.people_list_item1, list);
this.context = context;
this.data = list;
this.id_list = id_list;
}
public View getView(final int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
LayoutInflater inflator = context.getLayoutInflater();
view = inflator.inflate(R.layout.people_list_item1, null);
final ViewHolder holder = new ViewHolder();
holder.title = (TextView) view.findViewById(R.id.tv_name);
holder.image = (ImageView) view.findViewById(R.id.avtaar);
holder.favorite = (CheckBox) view.findViewById(R.id.fav);
view.setTag(holder);
holder.favorite.setTag(data.get(position));
holder.favorite.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Model element = (Model) holder.favorite.getTag();
element.setSelected(buttonView.isChecked());
}
});
} else {
view = convertView;
((ViewHolder) view.getTag()).favorite.setTag(data.get(position));
}
ViewHolder holder = (ViewHolder) view.getTag();
holder.favorite.setChecked(data.get(position).isSelected());
holder.title.setText(data.get(position).getName());
try {
holder.image.setImageBitmap(openPhoto(Long.valueOf(id_list.get(position))));
} catch (Exception e) {
e.printStackTrace();
}
return view;
}
static class ViewHolder {
protected TextView title;
protected CheckBox favorite;
ImageView image;
}