2

Help me please.
I use Coil to show images in grid RecyclerView.
The implementation is very straightforward - in each viewholder.bind() i call image.load(URL).
URL is static URL = "https://loremflickr.com/200/200/" and simply provides a new random picture on each request .
When RecyclerView creates holders on app launch, image.load(URL) works just fine, loading new image for each holder.
Problem: When I start to scroll the recycer, image.load(URL) just takes latest downloaded picture instead of downloading new one. I used loggerInterceptor to see that image.load(URL) performs real http calls only for first portion of holders.
Question: How can I make Coil to download new picture for each viewholder in recyclerView, not only for first group of visible holders?

enter image description here

The holder:

class ImageViewHolder(val binding: ItemImageBinding) : RecyclerView.ViewHolder(binding.root) {
 
    fun bind() {
        binding.image.load(URL){}
    }
 
    companion object {
        fun create(parent: ViewGroup): ImageViewHolder {
            val layoutInflater = LayoutInflater.from(parent.context)
            val binding = ItemImageBinding.inflate(layoutInflater)
            return ImageViewHolder(binding)
        }
    }
}

The adapter:


class ImageRvAdapter(val list: MutableList<ImageModel>) : ListAdapter<ImageModel, ImageViewHolder>(
    IMAGE_COMPARATOR
) {
 
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ImageViewHolder {
        return ImageViewHolder.create(parent)
    }
 
    override fun onBindViewHolder(holder: ImageViewHolder, position: Int) {
        holder.bind()
    }
 
    companion object {
        val IMAGE_COMPARATOR = object : DiffUtil.ItemCallback<ImageModel>() {
            override fun areItemsTheSame(oldItem: ImageModel, newItem: ImageModel): Boolean {
                return newItem::class == oldItem::class
            }
 
            override fun areContentsTheSame(oldItem: ImageModel, newItem: ImageModel): Boolean {
                return oldItem == newItem
            }
        }
    } }

Adapter setup:

   //Data model for list
    sealed class ImageModel{
        object Image:ImageModel()
    }
    //Adapter setup
    lateinit var adatper: ImageRvAdapter
    private fun initRecyclerView() {
        //creating a list of 140 items
        val imageList: MutableList<ImageModel> = mutableListOf()
        for (i in 0..139){  
            imageList.add(ImageModel.Image)
        }
        //adapter stuff
        adatper = ImageRvAdapter()
        binding.recyclerView.layoutManager = GridLayoutManager(
            this,
            6,
            GridLayoutManager.HORIZONTAL,
            false
        )
        binding.recyclerView.adapter = adatper
        adatper.submitList(imageList) 
    }
Waldmann
  • 1,563
  • 12
  • 25
  • What is `URL` in `binding.image.load(URL)` ? how r u getting the `URL`? can u add it with question – ADM Feb 10 '21 at 10:12
  • @ADM, done. On each new request this same url provides one random image. – Waldmann Feb 10 '21 at 10:19
  • 1
    So u mean u call load with `https://loremflickr.com/200/200/` each time and it provids the random images ? if thats what u mean. then u have to disable cache in Coil . Check their documentation to disable cache . – ADM Feb 10 '21 at 10:21
  • If that's not case we need to know how r u assigning random images . because this seems to be broken. Pls add code how r u assigning random image to a postion – ADM Feb 10 '21 at 10:24
  • .memoryCachePolicy(CachePolicy.DISABLED) fixed the problem. Post the answer I will mark It as a correct solution – Waldmann Feb 10 '21 at 10:28
  • @ADM, Is there any conventional way I can cache the loaded images so RV will not load it again when I scroll back to the beginning? Currently image is loaded righti into the view and the view is destoryed the image is lost – Waldmann Feb 10 '21 at 10:37
  • 1
    This is bad approach . Whole idea of using a image loader is to keep cache . I think there is something wrong with your random image logic . I never used `Coil` so can not comment on it. can u try adding a `placeholder` to image . – ADM Feb 10 '21 at 10:38
  • What you mean y placeholder? A Coil placeholder feature? I added it and it had no effect on caching. Random image logic is what I got to work with, not my choice. – Waldmann Feb 10 '21 at 10:49
  • 2
    @ADM solved it as well. just added memoryCacheKey(), so now it knows how to distinguish between a new and a stored content. You completely made my day, thank you very much. Not by giving direct answers but by pushing in right direction. Here is some cool stuff, maybe you will like it https://www.youtube.com/watch?v=4aFGuKwF2ic&ab_channel=DanHate666 \m/ – Waldmann Feb 10 '21 at 11:04

0 Answers0