RecyclerView(5) 使用 DiffUtil 刷新列表內(nèi)容

RecyclerView 這一系列文章是基于一個示例, 可以忽略示例實現(xiàn)細節(jié).
主要關(guān)注通用點.

1. 實現(xiàn) DiffUtil.ItemCallback

在 Adapter 文件中, 創(chuàng)建頂級類
并將 數(shù)據(jù)類型 作為參數(shù)傳遞.

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

需要實現(xiàn) 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 // 是否包含相同的數(shù)據(jù):SleepNight 是一個數(shù)據(jù)類,此相等性檢查將檢查所有字段(Data 類自動定義的)
    }
}

2. 使用 ListAdapter 管理列表.

RecyclerView 提供適配器類 ListAdapter,可構(gòu)建由列表支持的 RecyclerView 適配器。

ListAdapter 會為跟蹤列表,并在列表更新通知適配器。

2.1 ListAdapter 源碼分析

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

看一下源碼,它也是 繼承自 RecyclerView.Adapter.
特別地是, 泛型 T 類 作為 數(shù)據(jù)的類型.
因此可知, 它也會管理數(shù)據(jù)的.

它的構(gòu)造函數(shù)需要一個參數(shù) 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 表示 數(shù)據(jù)類型,
ViewHolder 原本的緩存
SleepNightDiffCallback 作為回調(diào)

2.3 刪除

SleepNightAdapter 中
(1)刪除 data字段, 因為 ListAdapter 會跟蹤列表
(2)刪除 getItemCount() , ListAdapter 已有實現(xiàn)
(3) 提供了 getItem, onBindViewHolder中使用它

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

submitList() 的方法,用于告知 ListAdapter 列表新版本。
調(diào)用此方法時:
(1)將新列表與舊列表進行差異比較,
檢測已添加、移除、移動或更改的項
(2)更新 RecyclerView 所顯示的項

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

至此, 已經(jīng)完成了 DiffUtil 的使用.
主要是
(1)借助與 ListAdapter 的實現(xiàn), 將DiffUtil.ItemCallback 作為參數(shù)傳遞;
(2)然后在數(shù)據(jù)變化時, 調(diào)用 ListAdapter.submitList;
(3)此時會回調(diào)自定義的ItemCallback, 比較新表和舊表, 確定哪些需要更新
(4)RecyclerView 上僅更新上面確定更新的項.

--- End ---

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容