I have this adapter that I load with data from the internet. It displays the wrong images for a split second before displaying the right one if I scroll down quickly. The corresponding text next to the images however does not do this. It's more obvious when it download even more data on the fly. Please help me debug this. Here's what the listview looks like:

The categoryAdapter is initialized with a list of data containing only textview data. When categoryAdapter's getView() is called, it downloads the image from a url through asynctask. A OnScrollListener downloads 12 more articles (again only text) when the bottom of the listview is reached. Here is getView(). Note that I thought recycling the old views was the problem, so I tried to set the image to null quickly before changing the imageview's drawable to the new image so that I wouldn't see the old one. This worked for not seeing the bug if I scroll up quickly, but not if I scroll down quickly. What could be the issue?
class CategoryAdapter extends BaseAdapter{...
@Override
public View getView(int i, View view, final ViewGroup viewGroup){
// crate a new rowItem object here
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row;
if (view == null) row = inflater.inflate(R.layout.single_row, viewGroup, false);
else row = view;
// Get the description, image and title of the row item
TextView title = (TextView) row.findViewById(R.id.textView);
TextView description = (TextView) row.findViewById(R.id.textView2);
ImageView image = (ImageView) row.findViewById(R.id.imageView);
ProgressBar pb = (ProgressBar) row.findViewById(R.id.progressBarSingleRow);
/* On getting view, set this to invisible until loaded. (issue before: old image seen
before new image on fast scroll) Mostly fixed by this, but on fast scroll down, still
shows a little */
image.setImageDrawable(null);
// Set the values of the rowItem
SingleRow rowTemp = articles.get(i);
title.setText(rowTemp.title);
description.setText(rowTemp.description);
String s = "null";
if (rowTemp.image != null) s = "not null";
Log.e("ImageLog", "Item " + Integer.toString(i) + ", is " + s);
// Load image into row element
if (rowTemp.image == null) { // download
// Prepare prepped row objects in single holder object for fetchCategoryImageTask
AdapterObject holder = new AdapterObject();
holder.title = title;
holder.description = description;
holder.image = image;
holder.pb = pb;
new FetchCategoryImageTask(rowTemp, holder).execute();
}
else { // set saved image
// Cropping image to preserve aspect ratio
image.setScaleType(ImageView.ScaleType.CENTER_CROP);
image.setCropToPadding(true);
image.setImageBitmap(rowTemp.image);
}
return row;
}
Just in case, here's a little of fetchCategoryImageTask()
@Override
protected void onPreExecute() {
image.setVisibility(ImageView.INVISIBLE);
}
@Override
protected Bitmap doInBackground(Void... params) {
return (sr.imageURL != null) ? downloadBitmap(sr.imageURL) : null;
}
@Override
protected void onPostExecute(final Bitmap b) {
// imageView image
// Preserve aspect ratio of image
image.setScaleType(ImageView.ScaleType.CENTER_CROP);
image.setCropToPadding(true);
image.setImageBitmap(b);
// Make image visible
image.setVisibility(ImageView.VISIBLE);
// Save image to SingleRow object for categoryAdapter's getView()
sr.image = b;
}
What is happening here is that ListViews reuse views. So it reuse a view that already has an image. I recommend you to use Volley library or ImageLoader library to solve this problem, it is easy to define a placeholder to show while the image is being downloaded.
So instead of use Asynctask, use the code below:
private void showImage(View view, String imageUrl) {
DisplayImageOptions options = new DisplayImageOptions.Builder()//
.showImageOnFail(R.drawable.image_placeholder)
.showImageOnLoading(R.drawable.image_placeholder)
.showImageForEmptyUri(R.drawable.image_placeholder)
.cacheInMemory(true)
.cacheOnDisk(true)
.build();
ImageLoader.getInstance().displayImage(imageUrl, imageViewType, options);
}
Universal Image Loader library: https://github.com/nostra13/Android-Universal-Image-Loader
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