在滚动期间,Android ListView和GridView重复更改项目

时间:2016-05-17 13:59:27

标签: android listview gridview

我想知道为什么ListView或GridView在滚动期间使用了旧项目?我有一个列表视图,我在列表视图中显示了500多种产品。每个列表项有4列,最后一列是ImageView,显示状态为活动或非活动。每当我将ImageView标记为活动时,在定期滚动后,每个项目都会自动将其ImageView更改为活动状态。

假设我点击了第6个项目并使其ImageView处于活动状态,那么在滚动期间我看到第12,18,24等也被更改为活动

2 个答案:

答案 0 :(得分:1)

为了优化滚动体验,ListViewGridView将重复使用项目视图,以避免为每个列表项目充气/实例化视图。

这就是为什么getView的{​​{1}}类型参数名为View的原因。当convertView为空时,您需要为该项目的新视图充气。当它不为空时,这意味着您可以重新使用此视图以避免通货膨胀的开销。

缺点是这个“循环”项目视图从上次显示时会有垃圾,你必须重置视图中的所有内容以匹配列表项。

新Android开发人员犯的一个常见错误是没有视图中所有内容的模型表示。例如,如果您的列表项可以显示活动或非活动状态,那么列表项的模型应该具有convertView属性boolean

列表的模型必须在任何给定时间具有列表的整个当前状态,以便只要mActive决定需要重新显示其列表项,就可以重新创建它。

所以你需要做的事情基本上是四件事:

  • 将属性添加到列表项模型中:

    ListView
  • 创建用于更改状态的适配器方法。例如:

        boolean mActive;    // this can be private with getter/setter
    

    在此处致电 public void toggleItemActive(int position) { mListItem.get(position).mActive = ! mListItem.get(position).mActive; notifyDataSetChanged(); } 非常重要。

  • notifyDataSetChanged()覆盖中使用此属性:

    getView
  • 从事件处理程序设置属性:

        imageView.setImageResource(item.mActive ? R.drawable.active : R.drawable.inactive);  // or however you are doing it
    

现在,您的 listView.setOnItemClickListener(new OnItemClickListener) { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { MyAdapter adapter = (MyAdapter) parent.getAdapter(); adapter.toggleItemActive(position); } }); 会正确显示您的列表项。

答案 1 :(得分:0)

我认为您在自定义适配器的getView()方法中使用了viewholder。当您使用视图持有者时,您将重用视图。从您的描述看起来,您的设备可以一次只列出6个列表项。因此,第6个,第12个(第6个位置+ 6个大小的屏幕),第18个(第12个位置+ 6个大小的屏幕),第24个等都将使用相同的视图。因此,当第6项改变时,相关的第12,第18,第24项等项目也将被改变。