3

I have a gridview which displays two column imageviews. I am loading these images with an async task (see this post Lazy load of images in ListView )

But when i am scrolling gridview , the images in positions are mixing. For example 14th image shows 1th image , i think view is trying to show old image before async task finishes.

My code :

    public Content getItem(int position) {
        return contents.get(position);
    }

    public long getItemId(int position) {
        return position;
    }

    @Override 
    public boolean hasStableIds() { return true; }

    public View getView(int position, View convertView, ViewGroup parent) {
        Thumbnail contentView;
        Content current = contents.get(position);
        if (convertView == null) {
            contentView = new Thumbnail(mContext);  
        }
        else {
            contentView = (Thumbnail) convertView;
        }

        contentView.title = current.getTitle();
        contentView.image = current.getImage();
        contentView.link = current.getLink();
        contentView.init();

        return contentView;
    }

Init function

    TextView titleText = (TextView)super.findViewById(R.id.titleText);
    titleText.setText(title);

    ImageView imageControl = (ImageView)super.findViewById(R.id.thumbImage);
    DrawableManager loadImage = new DrawableManager();              loadImage.fetchDrawableOnThread(imgUrl, imageControl);

Waiting for your help

Thanks

Community
  • 1
  • 1
dracula
  • 4,413
  • 6
  • 26
  • 31

2 Answers2

3

It happens because of resource reusing. What you should do:

  1. First, just set some kind of default image to your imageView (contentView.image.setImageResource(DEFAULT_RESOURCE)) inside getView method (transitional default picture is better than wrong one).

  2. Set unique tag to your image, for example, position or url of image to load (contentView.image.setTag(url)). When AsyncTask finishes, you can use some checks like

    String url=(String)imageView.getTag();
    
    if (url.equals(mUrl)) { //mUrl can be transmitted to AsyncTask instance separately
        mActivity.runOnUiThread(new Runnable() {
    
        @Override
        public void run() {
            imageView.setImageDrawable(bmp);
        });
    });
    }
    

It's needed because Adapter does not allocate memory for all N ImageView for N items. It stores just required amount for visible items and some reserved ImageViews. So there is no warranty that ImageView reference that you store will be actual within several seconds cause it can became invisible and be reused by visible ones.

Andrei Buneyeu
  • 6,662
  • 6
  • 35
  • 38
  • added this line. But nothing changed. It shows an old image and changes with new one when async task finishes. Also it shows wrong image sometimes. I think async task points wrong imagecontrol. Also tried setting tag to imageview. – dracula Apr 30 '13 at 11:47
  • Yeah, that can happen because of view reusing too (for example, ImageView that became invisible because of flowing over the edge of the screen can be reused for visible View with the same memory pointer). But setting tag definitely should help you (and helped me several times). – Andrei Buneyeu Apr 30 '13 at 12:05
  • setting url tag and comparing tag with url string worked for me :) Thank you very much Andrei. It was really big headache – dracula Apr 30 '13 at 12:34
  • glad to help you, pressing "accept" button would be appreciated :) – Andrei Buneyeu Apr 30 '13 at 13:41
0

Don't load images yourself. Use Universal Image Loader . It can cache, images and loaded bitmaps. Making your problem go away. It also supports showing stub images and automatic pause on scrolling and so on.

It solves your specic problems by only loading an image for the last instance of an imageView if you reuse it.

imageLoader.displayImage(imageUri, imageView);

Is all that is needed to asynchronously load an image.

richardwiden
  • 1,584
  • 2
  • 12
  • 22
  • I am using DrawableManager.. See 2th post. http://stackoverflow.com/questions/541966/how-do-i-do-a-lazy-load-of-images-in-listview – dracula Apr 30 '13 at 12:27
  • The post is 3 years old. The world has changed. Use UIL. Just look further down in the question you posted. – richardwiden Apr 30 '13 at 12:32