简体   繁体   English

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

[英]Android ListView and GridView repeating changed item during scroll

I am wondering why ListView or GridView used old items during scroll? 我想知道为什么ListView或GridView在滚动过程中使用旧项目? I have a list view more than 500 products i am showing in list view . 我有一个列表视图,我在列表视图中显示了500多种产品。 Each list item has 4 columns the last column is a ImageView showing status as active or inactive. 每个列表项有4列,最后一列是ImageView,显示状态为活动或非活动。 Whenever i marked ImageView as active then after scrolling periodically every item automatically changed its ImageView as active. 每当我将ImageView标记为活动状态后,定期滚动后,每个项目都会自动将其ImageView更改为活动状态。

Let suppose if i clicked on 6th Items and make its ImageView as active then during scroll i see that 12th , 18th , 24th and so on also changed as active 假设我单击了第6个项目,并将其ImageView设置为活动状态,那么在滚动过程中,我看到第12、18、24等也更改为活动状态

In order to optimize the scrolling experience, ListView and GridView will re-use item views to avoid having to inflate/instantiate a view for every list item. 为了优化滚动体验, ListViewGridView将重新使用项目视图,以避免必须为每个列表项目添加/实例化视图。

That's why getView has a parameter of type View called convertView . 这就是为什么getView具有View类型的参数称为convertView When convertView is null, you need to inflate a new view for the item. convertView为null时,您需要为该项目添加一个新视图。 When it is not null, that means you can re-use this view to avoid the overhead of inflation. 当它不为null时,这意味着您可以重新使用此视图以避免通货膨胀的开销。

The downside is that this "recycled" item view will have garbage in it from the last time it was displayed, and you have to reset everything in the view to match the list item. 不利的一面是,从上一次显示此“已回收”的项目视图起,便会出现垃圾,并且您必须重置视图中的所有内容以匹配列表项目。

So a common mistake that new Android developers make is to not have a model representation of everything in the view. 因此,新的Android开发人员常犯的一个错误是没有视图中所有内容的模型表示。 For example, if your list item can show a status of active or inactive, then the model for your list item should probably have a boolean property called mActive . 例如,如果您的列表项可以显示活动状态或非活动状态,则列表项的模型可能应该具有一个名为mActiveboolean属性。

The model for the list has to have the entire current state of the list at any given time, so that it can be recreated whenever the ListView decides it needs to redisplay its list items. 列表模型必须在任何给定时间都具有列表的整个当前状态,以便可以在ListView决定需要重新显示其列表项时重新创建它。

So what you need to do is basically four things: 因此,您基本上需要做的四件事:

  • Add the property to your list item model: 将属性添加到列表项模型:

      boolean mActive; // this can be private with getter/setter 
  • Create an adapter method for changing the state. 创建用于更改状态的适配器方法。 For example: 例如:

      public void toggleItemActive(int position) { mListItem.get(position).mActive = ! mListItem.get(position).mActive; notifyDataSetChanged(); } 

    Calling notifyDataSetChanged() here is very important. 在这里调用notifyDataSetChanged()非常重要。

  • Use this property in your getView override: getView重写中使用此属性:

      imageView.setImageResource(item.mActive ? R.drawable.active : R.drawable.inactive); // or however you are doing it 
  • Set the property from your event handler: 从事件处理程序设置属性:

      listView.setOnItemClickListener(new OnItemClickListener) { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { MyAdapter adapter = (MyAdapter) parent.getAdapter(); adapter.toggleItemActive(position); } }); 

Now your ListView will correctly display your list items. 现在,您的ListView将正确显示您的列表项。

I think you are using viewholder inside getView() method of your custom adapter. 我认为您在自定义适配器的getView()方法内部使用了viewholder。 When you are using view holder you will be reusing the views. 使用视图持有者时,将重新使用视图。 From your description it looks like, your device can diaply 6 list items at a time. 根据您的描述,您的设备一次可以显示6个列表项。 So 6th, 12th (6th position + 6-size of screen), 18th (12th position + 6-size of screen), 24th etc will all be using the same view. 因此,第6,第12(第6位置+屏幕的6尺寸),第18(第12位置+屏幕的6尺寸),第24等都将使用相同的视图。 Therefore, when 6th item is changed the related 12th, 18th, 24th etc items will also be changed. 因此,当第6项更改时,相关的第12、18、24等项也将更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM