RecyclerView(5) 使用 DiffUtil 刷新列表内容

RecyclerView 这一系列文章是基于一个示例, 可以忽略示例实现细节.
主要关注通用点.

1. 实现 DiffUtil.ItemCallback

在 Adapter 文件中, 创建顶级类
并将 数据类型 作为参数传递.

class SleepNightDiffCallback : DiffUtil.ItemCallback<SleepNight>() {
}

需要实现 ItemCallback 里的两个方法:
areItemsTheSame 和 areContentsTheSame

完整如下:

class SleepNightDiffCallback : DiffUtil.ItemCallback<SleepNight>(){
    override fun areItemsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
        return oldItem.nightId == newItem.nightId // nightId 相同 则 认为 是相同的item
    }

    override fun areContentsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
        return oldItem == newItem // 是否包含相同的数据:SleepNight 是一个数据类,此相等性检查将检查所有字段(Data 类自动定义的)
    }
}

2. 使用 ListAdapter 管理列表.

RecyclerView 提供适配器类 ListAdapter,可构建由列表支持的 RecyclerView 适配器。

ListAdapter 会为跟踪列表,并在列表更新通知适配器。

2.1 ListAdapter 源码分析

public abstract class ListAdapter<T, VH extends RecyclerView.ViewHolder>
        extends RecyclerView.Adapter<VH> {

看一下源码,它也是 继承自 RecyclerView.Adapter.
特别地是, 泛型 T 类 作为 数据的类型.
因此可知, 它也会管理数据的.

它的构造函数需要一个参数 DiffUtil.ItemCallback

    protected ListAdapter(@NonNull DiffUtil.ItemCallback<T> diffCallback) {
        mHelper = new AsyncListDiffer<>(new AdapterListUpdateCallback(this),
                new AsyncDifferConfig.Builder<>(diffCallback).build());
    }

2.2 ListAdapter使用

修改成:

class SleepNightAdapter : ListAdapter<SleepNight, SleepNightAdapter.ViewHolder>(SleepNightDiffCallback()) {

SleepNight 表示 数据类型,
ViewHolder 原本的缓存
SleepNightDiffCallback 作为回调

2.3 删除

SleepNightAdapter 中
(1)删除 data字段, 因为 ListAdapter 会跟踪列表
(2)删除 getItemCount() , ListAdapter 已有实现
(3) 提供了 getItem, onBindViewHolder中使用它

2.4 使用 submitList() 及时更新列表

submitList() 的方法,用于告知 ListAdapter 列表新版本
调用此方法时:
(1)将新列表与旧列表进行差异比较,
检测已添加、移除、移动或更改的项
(2)更新 RecyclerView 所显示的项

sleepTrackerViewModel.nights.observe(viewLifecycleOwner, Observer {
   it?.let {
       adapter.submitList(it)
   }
})

至此, 已经完成了 DiffUtil 的使用.
主要是
(1)借助与 ListAdapter 的实现, 将DiffUtil.ItemCallback 作为参数传递;
(2)然后在数据变化时, 调用 ListAdapter.submitList;
(3)此时会回调自定义的ItemCallback, 比较新表和旧表, 确定哪些需要更新
(4)RecyclerView 上仅更新上面确定更新的项.

--- End ---

参考指南:
https://developer.android.com/codelabs/kotlin-android-training-diffutil-databinding?hl=zh-cn#4

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容