How to avoid flickering while updating gridview?
Asked Answered
S

9

11

I have a gridview. Im displaying images from the array of 10 images. After 1 minute i'm adding 5 more images. To update the gridview i'm using the following code.

aImgAdapterL.notifyDataSetChanged();  

aImgAdapterL is my ImgaeAdapter. The new images are getting displayed.
My problem is when updating the gridview one flickering or blinking happening during the image updation. Is it possible to hide that flickering?

Sucker answered 27/11, 2012 at 10:27 Comment(7)
Do you have TextView's in items, showing ellipsized/truncated text ?Reynaldoreynard
Did you call notifyDataSetChanged() in quick succession, like each time you add one image ?Reynaldoreynard
no i added all the 5 images in the array and called notifydatasetchanged()Sucker
Sure, GridView must redraw itself and minimal flicker is normal, unless there's something that makes it slow for GridView to load images. Does you adapter do something heavy in getView() ?Reynaldoreynard
ya i'm telling about the minimal flickering. Is it possible to avoid that?Sucker
Found anything with this? I'm facing the same issue here with Galaxy S3.Bagel
can you show us the code on the getView()? maybe you are not recycling the view or something like that.Asceticism
S
7

I had the same issue and was able to solve it like this:

In fact it was due to my ListAdapter which didn't managed properly the case when the whole list is refreshed. If so, what you want to do is keeping the items already displayed on the screen as-is.

To do so, in the method getView of the Adapter when you get a recycled item, you must check if it's not already the one you want to display. If it's the case, just return it directly.

@Override
public View getView(int position, View convertView, ViewGroup container) {
    ImageView imageView;
    String src = this.getItem(position).getSrcThumbnail();
    if (convertView == null) {
        imageView = new ImageView(getContext());
        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);

        int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 120, getResources().getDisplayMetrics());

        imageView.setLayoutParams(new GridView.LayoutParams(GridView.LayoutParams.MATCH_PARENT, height));

    } else {
        imageView = (ImageView) convertView;

        // When you get a recycled item, check if it's not already the one you want to display.
        String newSrc = (String) imageView.getTag();

        if(newSrc.equals(src)){
            // If so, return it directly.
            return imageView;
        }
    }

    loadBitmap(this.getItem(position).getSrcThumbnail(), imageView);

    // Here you set the unique tag that allow to identify this item.
    imageView.setTag(src);

    return imageView;
}
Sweetmeat answered 17/7, 2014 at 12:10 Comment(1)
Glide doesn't allow you to set a tag to the image.Fonteyn
R
6

If your adapter has stable ids, override hasStableIds to return true.

Grep the android.GridView source code here, it allows the grid view to reuse a view for the same data rather than do a full redraw. This might help in the OP's case, because by default hasStableIds returns false.

Rash answered 17/8, 2014 at 3:3 Comment(3)
Can you please explain how this will minimize the flickering?Disvalue
@Disvalue Grep the android.GridView source code here: goo.gl/Nq4kpQ, it allows the grid view to reuse a view for the same data rather than do a full redraw. This might help in the OP's case, because by default hasStableIds returns false.Rash
Please add that explanation to your answer.Disvalue
G
1

Flickering occurs because the updating the UI is heavy.Please check weather you are doing cpu intensive functions like image cropping in the getview() of the adapter.The idea is to keep the getview() function simple and do the process intensive logic in separate threads.

Gallaher answered 18/8, 2014 at 13:4 Comment(0)
K
1

The solution is to not reload your image when it did not change.

In your adapters getView() do:

// schedule rendering:
final String path = ... (get path here);
if (holder.lastImageUrl == null || !holder.lastImageUrl.equals(path)
                || holder.headerImageView.getDrawable() == null) {
    // refresh image
    imageLoader.displayImage(imageUri, imageAware);
} else {
    // do nothing, image did not change and does not need to be updated
}

on success (add a ImageLoadingListener) you set holder.lastImageUrl = path, on fail and cancel you set holder.lastImageUrl to null so that it will reload next time.

Kelsey answered 19/9, 2014 at 10:15 Comment(1)
Thanks, it helped (combined with hasStableIds = true).Deadly
M
0

Use nostra13's Universal Image Loader on showing your images, set some animations while showing it.

...DisplayImageOptions.displayer(FadeInBitmapDisplayer)...
Mindy answered 4/10, 2013 at 5:37 Comment(0)
E
0

here i wrote a detailed example how to use viewholder pattern:

With this approach you can avoid flickering.

Emileeemili answered 2/7, 2015 at 7:26 Comment(0)
A
0

Pass ImageViewAware (instead of ImageView) which doesn't consider actual view size: Intead of:

imageLoader.displayImage(imageUri, imageView);

do following:

ImageAware imageAware = new ImageViewAware(imageView, false)
imageLoader.displayImage(imageUri, imageAware);
Aggravation answered 14/8, 2015 at 6:52 Comment(0)
I
0

Simple solution is 1) Have a method in your adapter that will append/reset your new data list into old array list and not to call notifyDataSetChanged() When user will scroll getview will get called and hence list will be updated. It should not flicker.

e.g. // Have a method in adapter class public void updateList(ArrayList<ABC> list) { /enter code here`/add to old one oldList.addAll(list); }

thats it `

Icbm answered 16/8, 2015 at 19:48 Comment(0)
C
0

You should enable OpenGL and hardware acceleration:

<application android:hardwareAccelerated="true" ...>

<uses-feature
  android:name="string"
  android:required=["true" | "false"]
  android:glEsVersion="integer" />

You can also using hardware caching on items of your gridview:

view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

Finally, you can overlay your grid view during update and play with transparency.

Congratulate answered 29/9, 2015 at 22:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.