Hi guys,
We are using Glide to load pictures/gifs in our app, but we are having a flickering issue.
Basically we used a RecyclerView to display a list of card(a news card to be specific, which contains both text and image/gif), in each card-view's instantiation method we would create TextViews or ImageViews in a for loop and add them to the card-view's LinearLayout. The problem is that when we try to use Glide to load images into ImageView, flikering would happen. Here's the codes:
the image item's layout
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:scaleType="centerCrop"
android:adjustViewBounds="true"
android:layout_centerInParent="true"
android:src="@drawable/image_loading_placeholder" >
</ImageView>
How we load images using Glide:
Glide.with(context)
.load(imageUrl)
.error(R.drawable.image_loading_placeholder)
.placeholder(R.drawable.image_loading_placeholder)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.transform(new MaxHeightResizeTransformation(activity, scaledUrl))
.into(v);
Do you guys have any clues on this issue ? Would really appreciate your help : )
Try reading #92 maybe gives some ideas.
Glide.....into?.dontAnimate() solve the problem?android:src to tools:src in XMLHi @TWiStErRob , we examined the possible problems you pointed out, but none of them solved the flickering problem:
Glide...into;tools:src also didn't work;You're saying you new and ImageView, that's contradicting with a layout XML quoted above.
So you re-create the view hierarchy of a card on every bind? That's a lot of layout cycles.
Could you explain when it flickers, for how long, etc.?
When do you add the new'd/inflated view into the hierarchy (before/after into())?
Oh, actuall what I mean is LayoutInflater.from(context).inflat() to "new" an ImageView, sorry for the misleading comments : )
Yeah we do re-create the view on every bind, actually performance isn't an issue, because the scrolling is really smooth ~
The inflated ImageView was added into the parent view after into().
Glide uses a ViewTreeObserver listener to wait for layout: please try to set up the view hierarchy fully, before loading image into it; not necessarily the problem, just a curtesy to Glide. Who knows, it may help. You could simply use inflate(R.layout...., holder.linearLayoutParent, true).
You didn't describe the flicker, please expand on that. Regardless, if you use holder.linearLayoutParent.removeAllViews() to reset the card in bind, consider using this in your adapter instead to reset a card:
@Override public void onViewRecycled(VH holder) {
ViewGroup p = holder.linearLayoutParent;
int count = p.getChildCount();
for (int i = 0; i < count; i++) {
// optionally you can check `if (child instanceof ImageView)` if you have many children
// but Glide should handle non-loaded/non-image Views
Glide.clear(p.getChildAt(i)); // stop loading and get rid of loaded image
}
p.removeAllViews();
}
This is more likely to help than having the View in the hierarchy before into.
Performance may not be an issue with removeAll/inflate, it's more the battery consumption; just because a device is fast enough it doesn't mean it has to be utilized more than necessary.
Hi,
Since I need a reference to the ImageView item, the ImageView was added to the parent view immediately after inflate() instead, but still there's flickering.
I uploaded a gif:

The only flicker I see is that the BAT...O2O line below the text disappears for one frame (split frames with http://ezgif.com/split):
FRAME34 
FRAME35 
FRAME36 
That looks like layout issue to me.
Hi, however before we used Picasso, and there wasn't flickering issue, so I'm really not sure about this ~
Please confirm that that's the flicker you're talking about, because you haven't explicitly said anything about "the flicker" yet :)
If it is, check your layout XML, for me it looks like a text on the left and an image on the right in a group view. The jump can be caused by either the text being empty (means text set async, less likely) or the image being empty while the image loads (more likely). Glide sets a placeholder every time when it starts loading: so if you don't set a placeholder, it will set null to clear the current view. If you rely on that ImageView giving the height of the parent layout (that is the parent has wrap content sizing) and the text matches the image height, the null image can shrink the whole row for a moment.
Hi the flickering issue seems to occur only occasionally, so I'm closing this issue, thanks~ : )
The filckering issue still occurs when i call notifyItemChanaged(payload, postion) in my adapter based on a particular interaction/onclicklistener on a button in the recyclerview item. The image flickers and tries to reload again.
I am using byte array to load my images in my cursor adapter, every time new data arrives, I notify data change and the image flicker, it really ugly. I tried .dontAnimate() and disk cache to source and still the same result. This is all that I have.
@Override
public void bindView(View view, Context context, Cursor cursor) {
ViewHolder viewHolder = (ViewHolder) view.getTag();
Device device = Device.fromCursor(cursor);
if (device.getImage().getBytes() != null) {
Glide.with(context).load(device.getImage().getBytes()).diskCacheStrategy(DiskCacheStrategy.SOURCE).dontAnimate().into(viewHolder.circleImageView);
}
}
Try removing android:adjustViewBounds="true" attribute from your image tag. I am also facing this same issue when I use android:adjustViewBounds="true" with the ImageView.
Quoting what I found here - https://stackoverflow.com/questions/36013709/how-to-avoid-image-flickering-in-a-listview
_I think the issue with this method is that there is a lot of flickering when one scrolls the listview since imageview height is not known in advance and images have to be scaled first using my width to calculate each image height in respect to it's aspect ratio._
Most helpful comment
The filckering issue still occurs when i call notifyItemChanaged(payload, postion) in my adapter based on a particular interaction/onclicklistener on a button in the recyclerview item. The image flickers and tries to reload again.