RecyclerView局部刷新-payload解决动态设置Item大小,图片重新加载问题

问题:页面切换全屏、半屏,列表的item 动态修改大小,item中的图片重新加载

最初直接实现了adapter中的onBindViewHolder抽象方法

less 复制代码
 public abstract void onBindViewHolder(@NonNull VH holder, int position);

切换全屏、半屏时,调用adapter.notifyDataSetChanged()onBindViewHolder中计算item的大小并重新设置,这样就会造成item中的图片重新加载,页面出现图片加载的过程,会有闪烁的现象。因为切换全、半屏幕,只需要对item的大小进行重新不需要图片及其他数据的重新加载。

出现这种情况时,就可以使用payload解决,那么paylaod是什么呢?

payloads 是一个与 RecyclerView.AdapternotifyItemChanged(int position, Object payload) 方法相关联的概念。这个方法允许你指定一个或多个对象(即 payloads)作为更新的一部分,这些对象可以被用来决定哪些部分的数据或视图需要被更新。

在传统的 notifyItemChanged(int position) 方法中,当你调用它时,RecyclerView 会认为指定位置的项(item)已经完全改变,并且会重新绑定(rebind)该位置的视图(View),这通常意味着整个视图都会被重新绘制,这可能会是一个比较昂贵的操作,尤其是在视图很复杂或者列表很长的情况下。

通过使用 notifyItemChanged(int position, Object payload) 并结合 onBindViewHolder(VH holder, int position, List<Object> payloads) 方法,你可以提供更精细的控制,告诉 RecyclerView 只有当特定的数据或视图部分受到影响时才需要更新。payloads 列表包含了你传递给 notifyItemChanged 方法的所有对象,这些对象在 onBindViewHolder 方法中被用来判断哪些部分需要更新。

在adapter 中存在另一个onBindViewHolder方法

less 复制代码
 public void onBindViewHolder(@NonNull VH holder, int position,
                @NonNull List<Object> payloads) {
            onBindViewHolder(holder, position);
        }

内部实现是调用了onBindViewHolder的抽象方法

onBindViewHolder中payloads是一个集合,里面存放的Object类型,结合notifyItemChanged(int position, Object payload)做一个局部更新操作。

kotlin 复制代码
override fun onScreenSizeStatusChanged(status: Int) {
    super.onScreenSizeStatusChanged(status)
    adapter.notifyItemRangeChanged(
        0,
        adapter.itemCount,
        BIND_PAYLOAD_SCREEN_SIZE_CHANGED //定义的常量
    )
}

上面的代码是在屏幕发生改变时的监听回调,在回调中进行列表视图的更新,通过notifyItemRangeChanged进行刷新。

在adapter中重写onBindViewHolder

kotlin 复制代码
override fun onBindViewHolder(
    holder: ViewHolder<RecyclerviewBinding>,
    position: Int,
    payloads: MutableList<Any>
) {
    payloads.firstOrNull {
        (it as? Int) == BIND_PAYLOAD_SCREEN_SIZE_CHANGED
    }?.let {
        // 重置 Item 大小
        holder.resetItemSize()
    } ?: onBindViewHolder(holder, position)
}

在此方法中,仅对item的大小进行处理重新设置。对其他数据不进行修改,如有需要更新的数据,可以在此更新。这样就处理就不会从新加载图片,造成图片加载闪烁的问题。

通过使用 payloads,可以显著提高 RecyclerView 更新时的性能,特别是在处理大量数据和复杂视图时。

相关推荐
xiangpanf3 小时前
Laravel 10.x重磅升级:五大核心特性解析
android
robotx6 小时前
安卓线程相关
android
消失的旧时光-19437 小时前
Android 面试高频:JSON 文件、大数据存储与断电安全(从原理到工程实践)
android·面试·json
dalancon8 小时前
VSYNC 信号流程分析 (Android 14)
android
dalancon8 小时前
VSYNC 信号完整流程2
android
dalancon8 小时前
SurfaceFlinger 上帧后 releaseBuffer 完整流程分析
android
用户69371750013849 小时前
不卷AI速度,我卷自己的从容——北京程序员手记
android·前端·人工智能
程序员Android9 小时前
Android 刷新一帧流程trace拆解
android
墨狂之逸才10 小时前
解决 Android/Gradle 编译报错:Comparison method violates its general contract!
android
阿明的小蝴蝶11 小时前
记一次Gradle环境的编译问题与解决
android·前端·gradle