i have read about the issue of getView called multiple times and all the answers. However, i don't find a solution for my problem.
I have a list where rows have two states: read or not. Well, i want to the items seen for first time have a different color and when i scroll the list, they change their color to "read state".
In order to do this, in the method getView of my adapter i set a field isRead when the row for that item is painted. But the problem is the following: since the method getView is called multiple times the field is marked as read and when the list is shown in the screen it appears as if it had already been read.
Any idea to fix this problem?
Thanks
I assume you mean the issue of getView requesting the same view several times.
ListView does this because it needs to get measurements for the views for different reasons (scrollbar size, layout, etc)
This issue can usually be avoided by not using the "wrap_content" property on your listview.
Other than that, using getView to determine if a view has been displayed is simply a bad idea. ListView has many optimizations that mess with the order getView is called on for each row, so there is no way to know what will happen and your app will start showing odd behavior.
Try to avoid any relationship between the view and the data other than the concept of view as a display of that data.
Instead, have some worker thread or event listener in your listactivity watch the list for which items in the list have been displayed to the user, update the data, and call dataSetChanged on your adaptor.
I had the same problem and I had no reference at all to "wrap_content" in the layouts attirbute. Although this is an old thread I couldn't figured it out how to solve the issue. Thus, I mitigated it by adding a List in the Adapter that holds the positions already drawn, as shown in the code below. I think that it is not the right away of doing that, but it worked for me.
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private List<Integer> usedPositions = new ArrayList<Integer>();
public ImageAdapter(Context c, List<String> imageUrls) {
mContext = c;
...
}
...
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
}
if (!usedPositions.contains(position)) {
// Your code to fill the imageView object content
usedPositions.add(position); // holds the used position
}
return imageView;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With