ImageViews which is in ListView doesn't displayed

I have ListView with EventAdapter.

public class EventAdapter extends BaseAdapter {
...
public View getView(int position, View view, ViewGroup parent) {
     ...
     cache.imgIcon.setImageDrawable(ImgCache.setImg(url, progressBar));
     ...
}

ImgCache its class for caching images.

public class ImgCache {
    public static HashMap<String, Drawable> imgCache;

    // get img from cache if exist, or download and put in cache
    public static Drawable setImg(final String link, final ProgressBar progressBar) {
        final Drawable[] image = {null};
        if (imgCache.containsKey(link)) {
            image[0] = imgCache.get(link);
            progressBar.setVisibility(View.INVISIBLE);
        } else {
            new AsyncTask<Void, Void, Drawable>() {
                @Override
                protected Drawable doInBackground(Void... params) {
                    URL url = null;
                    try {
                        url = new URL(link);
                        URLConnection connection = url.openConnection();
                        image[0] = Drawable.createFromStream(connection.getInputStream(), "src");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    imgCache.put(link, image[0]);
                    return image[0];
                }

                @Override
                protected void onPostExecute(Drawable result) {
                    progressBar.setVisibility(View.INVISIBLE);
                }
            }.execute();
        }
        return image[0];
    }
}

What the problem is?

After I open my Activity with ListView all images begin loading. But after the loading is finished they don't displayed. It is looks like:

Then I try to scroll 2 items down and then return to previous position. After this manipulation I can see 2 upper items with images. Also all images down are also visible when I scroll to them.

Answers


According to your problem, it seems like you need to refresh your ListView after the images has been downloaded (because when you scroll they do appear):

adapter.notifyDataSetChanged();

AsyncTask is asynchronous so the flow for your app is:

ListView Item needs to be displayed -> Calls Adapter.getView(...) for List item -> if image is not in cache, execute AsyncTask and return (not waiting for result) So, when you scroll down and back up, the Adapter.get(...) method is called again, however this time the image is in cache so it returns the Drawable object which is displayed

One way to resolve this issue would be to have a callback to the Adapter from the AsyncTask that will update the image once it is retrieved calling notifyDataSetChanged on the Adapter, setting specific Drawable directly or something similar (display a loading gif for images in the meanwhile?)

Or

Call the AsyncTask get(long timeout, TimeUnit unit) method which will block the man thread and wait for the AsyncTask to finish. After it is finished then it will return the result (your Drawable in this case). This will cause the main UI thread to hang while fetching images, so not optimal way to go about this.


Need Your Help

ArgumentError: message representative out of range when using the rsa gem

ruby-on-rails ruby encryption rsa public-key-encryption

I am getting this error when trying to encrypt big messages. I wonder whether this is a limitation with rsa.rb or if I am doing something wrong. Did anyone bump against this error?

Ruby hash direct access vs merge

ruby hash merge

Is there any difference between:

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.