diffutil局部刷新_RecyclerView中 各种节能刷新 和重点DiffUtil

本文详细介绍了RecyclerView的刷新方式,包括大量数据修改时的notifyDataSetChanged()和局部刷新如notifyItemChanged()等方法。重点讲解了DiffUtil的使用逻辑和步骤,如何实现对比新旧数据的回调,并强调了areItemsTheSame()和areContentsTheSame()方法的重要性。同时,文章揭示了使用DiffUtil可能遇到的问题,如数据对象变化导致的点击事件错位和内存泄漏,并提供了正确的onBindViewHolder()使用原则和避免问题的解决方案。
摘要由CSDN通过智能技术生成

你瞅啥?

RecyclerView的刷新基本分为以下两种情况:

1. 如果大量的数据被修改或者被修改数据的位置不确定,这个方法很消耗性能,不到万不得已不要使用,请尽量使用下面的刷新方法。实现如下:

adapter.notifyDataSetChanged();

2. 刷新某一项,定点刷新(常用),消耗性能很少,但是会有定位的问题,可能在过程中需要遍历集合获取操作下标

//刷新某Item中的所有组件

adapter.notifyItemChanged(position);

//刷新某Item中的部分组件

adapter.notifyItemChanged(position, payloads);

//插入Item

adapter.notifyItemInserted(position);

//删除Item

adapter.notifyItemRemoved(position);

//移动Item

adapter.notifyItemMoved(position, position + 1);

DiffUtil的运用逻辑非常简单,大致如下:

实现对比新旧数据的方法(类似比较器),这样DiffUtil便知道当新数据来临时,该不该更新某个item。

更新数据时,把新旧数据丢给DiffUtil,底层会根据你实现的对比方法,利用一种差分算法自动计算出差异,最后局部更新到UI。

DiffUtil的使用也很简单:

1、先实现比较新旧数据的回调,可以是一个独立的类,也可以写成Adapter的内部类:

public class BaseXXXAdapter extends RecyclerView.Adapter {

// ...

private class DiffCallback extends DiffUtil.Callback {

private List oldData, newData;

DiffCallback(List oldData, List newData) {

this.oldData = oldData;

this.newData = newData;

}

@Override

public int getOldListSize() {

return oldData.size();

}

@Override

public int getNew

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Android DiffUtil 是一个非常有用的工具类,可以帮助我们避免整个 RecyclerView刷新,只需要刷新发生变化的部分即可。下面介绍一下如何在低版本的 Android 系统使用 DiffUtil: 1. 添加依赖库 在项目的 build.gradle 文件,添加以下依赖库: ``` dependencies { implementation "androidx.recyclerview:recyclerview:版本号" } ``` 2. 创建 DiffUtil.Callback 实现类 创建一个实现 DiffUtil.Callback 接口的类,该接口有四个方法需要实现: - getOldListSize():返回旧数据集合的大小。 - getNewListSize():返回新数据集合的大小。 - areItemsTheSame():判断两个数据是否是同一个对象。 - areContentsTheSame():判断两个数据内容是否相同。 例如: ``` class MyDiffCallback(private val oldList: List<String>, private val newList: List<String>) : DiffUtil.Callback() { override fun getOldListSize(): Int { return oldList.size } override fun getNewListSize(): Int { return newList.size } override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { return oldList[oldItemPosition] == newList[newItemPosition] } override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { return oldList[oldItemPosition] == newList[newItemPosition] } } ``` 3. 调用 DiffUtil.calculateDiff() 方法 在需要更新数据的地方,创建一个 DiffUtil.Callback 实例,并调用 DiffUtil.calculateDiff() 方法,该方法会返回一个 DiffUtil.DiffResult 实例,我们可以在该实例的 dispatchUpdatesTo() 方法调用 RecyclerView.Adapter.notifyItemRangeChanged() 方法来更新 RecyclerView 的数据。 例如: ``` val diffCallback = MyDiffCallback(oldList, newList) val diffResult = DiffUtil.calculateDiff(diffCallback) diffResult.dispatchUpdatesTo(adapter) ``` 通过以上步骤,我们就可以在低版本的 Android 系统使用 DiffUtil 来避免整个 RecyclerView刷新,只需要刷新发生变化的部分即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值