每当在 recyclerview 中为 base64 图像调用 notifydatasetchanged() 时,图像就会闪烁

Posted

技术标签:

【中文标题】每当在 recyclerview 中为 base64 图像调用 notifydatasetchanged() 时,图像就会闪烁【英文标题】:Image blinks whenever notifydatasetchanged() called in recyclerview for base64 image 【发布时间】:2019-03-29 07:53:05 【问题描述】:

我在我的项目中使用 glide 在回收站视图中显示图像。图像将从服务器下载,直到我显示分辨率非常低的模糊图像。模糊后的图像是 base 64 编码的图像,将转换为 byteArray 以显示在 glide 中。

我的问题是每次调用notifydatasetchanged() 函数时,base 64 解码图像都会闪烁。如何避免这种奇怪的行为?

我在同一个回收站视图中将本地存储中的图像作为文件加载,但在调用notifydatasetchanged() 时没有闪烁问题。 仅针对模糊图像(base 64 解码位图)出现闪烁问题

我使用的是 glide 版本:4.8.0

//converting string to byteArray
byte[] blurImg = getBlurImageBitmap(fileDataTable.get("blurimg") as String)

//function which converts the image string to byteArray
fun getBlurImageBitmap(blurImageString : String) : ByteArray 
    val decodedBytes = Base64.decode(blurImageString, android.util.Base64.DEFAULT)
    return decodedBytes


//loading the byteArray into glide
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) 
    Glide.with(imageMessage.context)
         .load(chatMessage.fileData.blurImg)
         .transition(DrawableTransitionOptions.withCrossFade(1))
         .into(imageMessage)

我想避免base 64图像在滑翔中闪烁。

【问题讨论】:

可能重复:***.com/questions/37944860/… 试过了,但没有解决我的问题。我已经用过 setStableIds(true) Why Glide blink the item ImageView when notifydatasetchanged的可能重复 针对老版本glide给出的解决方案。即使当我更改为旧版本时仍然会出现问题 【参考方案1】:

找到图像闪烁的原因。

发现只有 base 64(模糊图像)编码的图像会导致闪烁问题,并且来自本地存储的图像不会闪烁。 每次刷新数据时,Glide 都会将 base 64 编码的字符串转换为可绘制的,因此会发生闪烁。而本地存储的位图是第一次处理并存储在LRU Cache中,所以再次刷新数据时不会加载。

在查看 glide 内部回调时发现,每当它将 base 64 字符串转换为可绘制对象时,它都会将 null 作为资源发送。

解决方案是提供一个与 base 64 解码的 drawable 相同的占位符 drawable 以滑行,以便在将 null 作为资源发送时显示该占位符可绘制对象。

Drawable image = new BitmapDrawable(((ImageViewHolder) holder).imageView.getContext().getResources(), BitmapFactory.decodeByteArray(imgList.get(position), 0, imgList.get(position).length));

//Passing the converted drawable as placeholder
requestOptions.placeholder(image);


Glide.with(imageViewHolder.imageView.getContext())
               .load(imgList.get(position))  -> Passing the same base 64 string which was converted to drawable for placeholder
               .apply(requestOptions)
               .into(imageViewHolder.imageView);


So the image actually flickers but we have passed the same image as placeholder, so the flicker will not be visible to use

【讨论】:

以上是关于每当在 recyclerview 中为 base64 图像调用 notifydatasetchanged() 时,图像就会闪烁的主要内容,如果未能解决你的问题,请参考以下文章

为啥 recyclerview$adapter 在片段中为空

有没有办法在代码中为 RecyclerView 启用滚动条?

如何在recyclerview(FirebaseRecyclerOptions)中为特定用户显示所有孩子

在 onBindViewHolder 中为 RecyclerView 设置 Firebase 实时数据库参考中的图像

如何在 Kotlin 中为 Android 的 RecyclerView 适配器初始化 viewHolder

如何在recyclerview中为cardview android设置带有int数组的onclicklistener