ListView数据在滚动时被清除[重复]
Posted
技术标签:
【中文标题】ListView数据在滚动时被清除[重复]【英文标题】:ListView Data got cleared on scrolling [duplicate] 【发布时间】:2015-05-29 06:03:02 【问题描述】:我正在开发一个显示listView
和checkBoxes
的应用程序。
当我滚动 listView
时,CheckBoxes
的值被清除。
下面是我的代码
适配器类:
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;
数据模型类
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;
不知道我哪里做错了。
【问题讨论】:
我猜你没有使用 notifydatasetchaned() 方法 你可以这样做:***.com/a/29208904/4693713谢谢.. 出现错误 > 隐式超级构造函数 ArrayAdaptersuper(....)
感谢我解决了这个错误
【参考方案1】:
我认为这是一个常见错误。您需要设置此代码
holder.favorite.setOnCheckedChangeListener(new OnCheckedChangeListener()
在 if/else 块之外。原因是 convertView is = null 是否需要设置监听器。我意识到您的代码可能需要一些安排,但我认为您可以比我做得更好,因为我的代码风格不同。这是否足够清楚?
另一个可能的错误是holder.favorite.setTag(position)
。原因是您的侦听器中的代码Model element = (Model) holder.favorite.getTag()
。您正在保存 int position
并将其类型转换为 Model
类,但无法正常工作。改覆盖getItem,先做编码。示例代码总结:
@Override
public Object getItem(int position)
return data.get(position); // return the Model
...
holder.favorite.setTag( getItem(position) );
注意:holder.favorite.setTag 应该设置在 outside if/else 块中。 if 块中只能设置 view.setTag(holder),因为它是一个新的视图对象。
除此之外,我认为你的代码设计应该可以工作!
建议的代码更改...
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
变化是:
-
我使用 不同 的 cmets 来强调代码更改。
ViewHolder holder
在 getView
() 中声明。删除类内顶部的持有人声明。我认为这是更好的编码风格,因为持有者更接近于找到您使用它的位置,使其成为本地 getView。
holder.favorite.setTag
和 view.setTag
的位置已切换。我认为这是一种更安全的编码风格。我认为在将其用作对象视图的参数之前先设置持有人会更安全。我承认,这可能无关紧要。
当 convertView is not = null 时,view.getTag
是必需的。当您在同一块中使用view.getTag()).favorite.setTag
设置标签时,您实际上是在以意外行为更改持有者的内容。
在代码 (Model) buttonView.getTag()
中,使用 buttonView 代替 holder.favorite。我希望这会得到正确的模型对象。
【讨论】:
有时我会发布示例代码,但我现在需要做一些事情。 我刚刚在“建议的代码更改”下完成了我发布的更新。我希望它对你也有意义。我们都会犯错。 哦..删除代码“ViewHolder holder = (ViewHolder) view.getTag();”在 else 块下。你不再需要那个地方的代码了。 让我们continue this discussion in chat.【参考方案2】:您必须保存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;
【讨论】:
我会尽力让你知道 你为什么要设置tag
两次holder.favorite.setTag(position);
&holder.favorite.setTag(data.get(position));
?
我试过你的代码,但它不适合我
为什么要扩展 ArrayAdapter在类似的情况下,如带有复选框、单选按钮、计数框等的列表视图,我使用如下操作 1)保持一个与listview(行数)大小相似的arraylist 2)这个数组/数组列表将在适配器类的构造函数中初始化,所有位置为零 3) 在声明复选框并将其标签设置为位置后的 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;
这总是可以解决我的列表视图滚动问题..
【讨论】:
我没有得到这个,你能在我的代码中修改它吗? @yushi 检查编辑【参考方案4】:改变这个..
@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;
【讨论】:
试过不适合我:(以上是关于ListView数据在滚动时被清除[重复]的主要内容,如果未能解决你的问题,请参考以下文章
如何使 WPF ListView 项目水平重复,如水平滚动条?
Flutter ListView.builder在滚动时结结巴巴并跳到顶部[重复]