question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Placeholder issue with reloading same images on recyclerView when the images are not in memory

See original GitHub issue

Hello - I’m running into some reload/flicker issues with gif/video frame support in RecyclerView. I think it might be related to https://github.com/coil-kt/coil/issues/280

We have RecyclerViews where notifyDataSetChanged() is called under certain conditions (when clicking on the item and etc.). I’m noticing some flicker when the same images should be re-bind but they aren’t loaded from memory.

For example, when the same image (I’m mostly seeing gif or video frame) is loaded after notifyDataSetChanged() from DISK, I’m noticing the issue from step 4 & 5 below.

  1. Coil image request starts and does fresh load for Image A
  2. notifyDataSetChanged() is called
  3. Coil image request starts again for Image A
  4. onStart() called on the view target to load placeholder
  5. Takes some time until onSuccess() to load from DISK

When I load with a custom ViewTarget and disable setting the placeholder, the step 4 doesn’t happen so the same image stays between the reload. This isn’t a solution because I do need to clear out the image when a new load starts, but I cannot differentiate if the view is binding from notifyDataSetChanged() or if it is a fresh load. I’m hoping there is a way not to call onStart() if we’re requesting the same image.

While I’m looking into why I’m not seeing the issue on Glide, I was wondering if you could advise if this can be handled from Coil. Thank you 🙇‍♂️

The resulting experience looks like this

reload

Code

From RecyclerView.Adapter

override fun onBindViewHolder(holder: SomeViewHolder, position: Int) {
  val request = ImageRequest.Builder(imageView.context)
    .data(uri)
    .target(imageView)
    .placeholder(R.color.some_placeholder)
    .build()
  myImageLoader.enqueue(request)
} 

override fun onViewRecycled(holder: SomeViewHolder) {
  CoilUtils.clear(holder.thumbnail)
}

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:13 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
seankim-androidcommented, Jul 16, 2021

Closing with updates. Thanks again for your suggestions and clarifications.

  1. Used a custom ViewTarget and some tagging logic to skip duplicate requests. This resolved the flicker issue on re-bind which is good enough for now.
  2. Global memory caching of animated images is indeed a lot of work with unknowns. Will look into the suggested option.

By far the easiest way to implement this is to have consumers manually add drawables back to a custom cache and reset them when they’re done with them.

  1. You’re right. I couldn’t find a way for Movie to support downsampling before draw time.
1reaction
seankim-androidcommented, Jul 13, 2021

@colinrtwhite I was trying to skip onStart() based on the result drawable from onSuccess(). I read it again and it does sound confusing 😃 Anyways, your suggestion makes sense for both onStart and onSuccess.

2 & 3 make a lot of sense. Thank you for all the clarifications. It does look like a lot of work and extra complexity. I’ll see if I can solve the issue with a custom ViewTarget first before trying to implement the other parts.

I’m hoping the tag or some other approach to skip the new request based on the previous request works out. My actual code from RecyclerView.Adapters are more tricky than what I posted in the description so I’ll try out few more things based on your response.

Thanks again for your response! I’ll either close this issue or come back with new questions in the next couple of days.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to stop images reloading in Recyclerview when scrolling
At first, there is a bug in your code - you have to remove the condition from onBindViewHolder . All ImageView instances has...
Read more >
RecyclerView - Glide v4 - GitHub Pages
RecyclerViewPreloader can automatically load images just ahead of where a user ... RecyclerView , you're loading images with into(ImageView) and you're not ......
Read more >
Picasso — Placeholders, Errors, and Fading - Future Studio
A better solution is to call .noPlaceholder() in the second Picasso request. This will keep the previous image in place until the second...
Read more >
Picasso Tutorial for Android: Getting Started
In this Picasso Tutorial, you'll learn how to use Picasso to load images from different sources and how to apply filters and transformations ......
Read more >
Solving the Android Image Loading Problem: An Updated Guide
However, I also warn students that it is not meant as a complete guide for loading an image in an Android app. It...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found