Reputation: 147
I am wondering why ListView or GridView used old items during scroll? I have a list view more than 500 products i am showing in list view . Each list item has 4 columns the last column is a ImageView showing status as active or inactive. Whenever i marked ImageView as active then after scrolling periodically every item automatically changed its ImageView as active.
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
Upvotes: 0
Views: 586
Reputation: 30985
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.
That's why getView
has a parameter of type View
called convertView
. When convertView
is null, you need to inflate a new view for the item. When it is not null, that means you can re-use this view to avoid the overhead of inflation.
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. 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
.
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.
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.
Use this property in your getView
override:
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.
Upvotes: 1
Reputation: 251
I think you are using viewholder inside getView() method of your custom adapter. 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. 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. Therefore, when 6th item is changed the related 12th, 18th, 24th etc items will also be changed.
Upvotes: 0