0

I have a List View of images.

If no image exists in the local cache, the placeholder image will remain in place of the image.

Then an asynchronous task is run to download the image from a server.

Once the async task finishes I set the imageView bitmap to the downloaded image. Then I call notifyDataSetChanged()

The problem is that I need to scroll down and scroll back up for each cell to show the new image that has been downloaded. It doesn't update the cells automatically.

So I have:

public class ImageLoadTask extends AsyncTask<Void, Void, Bitmap> {

    private ImageView imageView;

    public ImageLoadTask(ImageView imageView) {
        this.imageView = imageView;
    }

    @Override
    protected Bitmap doInBackground(Void... params) {

        // download image from server and return     
    }

    @Override
    protected void onPostExecute(Bitmap result) {
        super.onPostExecute(result);
        imageView.setImageBitmap(result)
        notifyDataSetChanged()
    }
}

and in my getView() method I have:

if(image exists in cache){
    myImageView.setBitmap(image in Cache);
}else{
    new ImageLoadTask(myImageView).execute()
}

So any images that were stored in the Cache work fine.

Any images that have to be downloaded first will not update correctly, unless you scroll down and back up again.

What is the problem?

Greg Peckory
  • 7,700
  • 21
  • 67
  • 114
  • i suggest you to use volley or Picasso library to load images. – Rubanraj Ravichandran Sep 04 '15 at 10:02
  • you need to do the following //Clear existing items `listAdapter.clear();` //Add new items `listAdapter.addAll(updatedvalues);` //Notify that the data has changed `listAdapter.notifyDataSetChanged();` – karan Sep 04 '15 at 10:02

2 Answers2

0

I believe you are doing thigs which have been already done and are working rly fine.

I advise you to use library for loading images with listview. One of these is picasso Picasso Android library. This library provides downloading and caching, and can easily (with one line) display them to imageview. Also it provides possibility for placeholder image.

Picasso.with(context)
  .load(url)
  .resize(50, 50)
  .centerCrop()
  .into(imageView)

Here is another question on stackoveflow: Using Picasso library with ListView

EDIT: If you use picasso you will ALSO solve problem with images wrong displaying while scrolling. This happens if you are loading/downloading them in AsyncTask and you are not doing it correctly.

I was answering question about this problem few daays ago: Why are wrong images getting loaded in ListView occasionally?

Community
  • 1
  • 1
  • I love this library... never heard of it before. I have a method called `setRoundedCorners(bitmap, left, right, top, bottom)`. And I would normally run the bitmap through here. How would I use this method with picasso? – Greg Peckory Sep 04 '15 at 12:11
  • You can use transform api of picasso [picasso](http://square.github.io/picasso/) take a look =) – Jaroslav Klech Sep 04 '15 at 13:20
0

Firstly, if you are using the ImageView object directly, then you don't need to call notifyDataSetChanged. Secondly, what you need to ensure is that the ImageView object you are passing still exists for the same URL requested, i.e., as you must know that Android will re-use views and might be if in between you had scrolled the ImageView object for which you had requested for an URL would have changed to some other URL.

I have worked on a very similar scenario, where I had a separate design like Adapter -> ImageViewRequest(This class will be used to post request, and this class maintains a map of ImageView and URL. So for every request entry is done to the map, and for every response we check that the response for the URL is the current requested URL for the entry of that ImageView and then set accordingly) -> AsyncTask And also ensure that while setting the bitmap you do that inside a runOnUIThread task to ensure that the image is properly loaded, otherwise you might get a crash saying you are setting in a wrong thread.

Hope that helps :)

Swagato
  • 106
  • 1
  • 2