2

I have a recyclerview with diffutil. Already I using Glide to load images inside the ImageViews.

on the onBindViewHolder I call my function it's called loadImage(holder.view,item)

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    val item = getItem(position)

    onLoadImage(holder.view, item)
}

In my loadImage I load the image inside the view.

 private fun loadImage(view: View, item: MyItemModel) {
        Timber.i("load item's image id: ${item.id} image is: ${item.image}")

        Glide.with(context)
                .asDrawable()
                .load(item.image)
                .into(view.main_image)
    }

It works good, but when first time when It's loading the image than I swipe in the list, and the Images are shows like this:

enter image description here

So the Images are duplicated, but the last two image is different. It happens only if I swipe fast when It's loading. Log:

I/MyListAdapter: load image into : 6 image is: [B@25d0674
I/MyListAdapter: load image into : 7 image is: [B@e64ced4
I/MyListAdapter: load image into : 8 image is: [B@b384734

This is a Custom View. Context is that's view's context.

So the Images are different. What is the problem?

Any suggestion?

DAA
  • 1,346
  • 2
  • 11
  • 19
vihkat
  • 895
  • 3
  • 13
  • 28

5 Answers5

3

I know its late but hope it will help someone. Override these two methods in your adapter.

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

  @Override
public int getItemViewType(int position) {
 return position;
}
Peter Haddad
  • 78,874
  • 25
  • 140
  • 134
mmfarzaneh
  • 381
  • 1
  • 11
  • This worked like a charm. How and Why ? Can you share the explanation please? – Mini Chip Jun 19 '22 at 16:03
  • I can not understand what you say @MiniChip – mmfarzaneh Jun 21 '22 at 07:10
  • Also having this issue with SDK v32. Just overriding getItemViewType seems to fix it for me but would also like to know why. Does the parent RecyclerView.Adapter cache the position that causes this to happen or something? – Ken Aug 18 '22 at 18:53
  • I think this solution work because RecyclerView will not recycle view anymore. as each item is one type. If RecyclerView dont recycle the view (which contain ImageView inside), then duplicated image will not happened This solution may work if your RecyclerView dont have many items, but it may a problem with performance if your RecyclerView have more items – Linh Nov 10 '22 at 02:07
3

Try clearing the image before loading a new one in your loadImage method:

view.main_image.setImageBitmap(null)
Glide.with(...)
DAA
  • 1,346
  • 2
  • 11
  • 19
0

If your image can come from both local drawable or remote url.
There is a chance that you will get duplicated image. Basically, your local image may be override by remote image.
Then before loading local drawable, you should cancel loading process which happened on this image

You can find the example here https://bumptech.github.io/glide/doc/getting-started.html

public void onBindViewHolder(ViewHolder holder, int position) {
    if (isLoadingRemoteImage) {
        ...
    } else {
        Glide.with(context).clear(holder.imageView);
        holder.imageView.setImageDrawable(specialDrawable);
    }
}
Linh
  • 57,942
  • 23
  • 262
  • 279
0
Glide.with(context)
        .setDefaultRequestOptions(RequestOptions().frame(1000000L)) // Set the time in microseconds
        .load(videoPath)
        .skipMemoryCache(true)
        .diskCacheStrategy(DiskCacheStrategy.NONE)
        .into(imageView)
Timchang Wuyep
  • 629
  • 7
  • 10
0

This will work for sure

override fun onBindViewHolder(holder: CategoriesViewHolder, position: Int){

    Glide.with(context)
        **.setDefaultRequestOptions(RequestOptions().frame(1000000L)) //add 
         this line only if you are using gif**
        .load(imgList[position])
        .skipMemoryCache(true)
        .diskCacheStrategy(DiskCacheStrategy.NONE)
        .into(holder.imageview)

    //Glide.with(holder.itemView).load(imgList[position]).into(holder.imageview)
}

this code ensure that the loaded image is not stored in memory (skipMemoryCache(true)) or on disk (diskCacheStrategy(DiskCacheStrategy.NONE)), so it's fetched fresh each time from the source.