RecyclerView | 在 RecyclerView 中使用 ListAdapter

本文是介紹 RecyclerView 入門 系列文章 的第二篇。若是您已經對建立 RecyclerView 有了必定的認識,請繼續閱讀本文。若是還沒有熟悉,建議您首先閱讀本系列中的 第一篇文章java

RecyclerView 能夠很高效地顯示列表數據。對於靜態的列表數據,默認的 adapter 足矣。然而,在多數狀況下,RecyclerView 的數據是動態變化的。拿備忘工做的應用舉例: 主要操做是添加新的工做事項,刪除已經完成的工做事項。notifyItemInserted() 能夠將新任務添加到指定位置,可是須要刪除元素的時候問題就來了,notifyItemRemoved() 只有在您已知待刪任務的位置時纔有效果。雖然能夠寫代碼來肯定待刪任務的位置,而後調用 notifyItemRemoved(),可是代碼會變得很是繁雜。調用 notifyDataSetChanged() 也是一個辦法,可是它會重繪整個視圖,包括數據未發生變化的部分,使得該操做的代價變大。而 ListAdapter 能夠處理元素的添加和刪除而無需重繪視圖,甚至能夠爲變化添加動畫效果。android

使用 ListAdapter 的另外一個好處是: 當添加或刪除元素的時候,還能夠添加動畫。這樣用戶能夠很直觀地看到列表數據的變化。雖然沒有 ListAdapter 也能夠實現動畫效果,可是這就須要開發者自行實現,而且因爲帶有動畫的視圖須要重繪,因此沒法達到一樣的性能表現。git

添加元素的動畫效果

添加元素的動畫效果

處理差別比較

DiffUtil 是 ListAdapter 可以高效改變元素的奧祕所在。DiffUtil 會比較新舊列表中增長、移動、刪除了哪些元素,而後輸出更新操做的列表將原列表中的元素高效地轉換爲新的元素。github

爲了可以識別新的數據,DiffUtil 須要您重寫 areItemsTheSame() 和 areContentsTheSame()。areItemsTheSame() 檢查兩個元素是否爲同一元素。areContentsTheSame() 檢查兩個元素是否包含相同的數據。app

areItemsTheSame() 比較元素的示意圖

areItemsTheSame() 比較元素的示意圖

areContentsTheSame() 比較元素的示意圖

areContentsTheSame() 比較元素的示意圖

Adapter 類中添加 DiffUtil 對象,而且複寫 areItemsTheSame()areContentsTheSame()ide

<!-- Copyright 2019 Google LLC. 
   SPDX-License-Identifier: Apache-2.0 -->

object FlowerDiffCallback : DiffUtil.ItemCallback<Flower>() {
   override fun areItemsTheSame(oldItem: Flower, newItem: Flower): Boolean {
      return oldItem.id == newItem.id
   }

   override fun areContentsTheSame(oldItem: Flower, newItem: Flower): Boolean {
      return oldItem == newItem
   }
}

Adapter 的父類由 RecyclerView.Adapter 改成 ListAdapter,並傳入 DiffCallback性能

<!-- Copyright 2019 Google LLC. 
   SPDX-License-Identifier: Apache-2.0 -->
   
class FlowerAdapter : ListAdapter<String, FlowerAdapter.FlowerViewHolder>(FlowerDiffCallback)

更新列表

ListAdapter 經過 submitList()) 方法獲取數據,該方法提交了一個列表來與當前列表進行對比並顯示。也就是說您無需再重寫 getItemCount(),由於 ListAdapter 會負責管理列表。動畫

Activity 類中,調用 AdaptersubmitList() 方法並傳入數據列表。google

<!-- Copyright 2019 Google LLC. 
   SPDX-License-Identifier: Apache-2.0 -->

val flowerList = resources.getStringArray(R.array.flower_array).toMutableList()
val flowerAdapter = FlowerAdapter()
flowerAdapter.submitList(flowerList)

Adapter 類中,onBindViewHolder() 如今可使用 getItem()) 從數據列表中獲取指定位置的元素了。spa

<!-- Copyright 2019 Google LLC. 
   SPDX-License-Identifier: Apache-2.0 -->

override fun onBindViewHolder(holder: FlowerViewHolder, position: Int) {
  holder.bind(getItem(position))
}

就這麼簡單。僅需幾步簡單操做就能夠在您的 RecyclerView 中使用 ListAdapter。如今您的應用能夠經過使用 ListAdapter 來更新那些發生變化的元素以得到更好的性能和用戶體驗了。

下一步

關於 ListAdapter完整示例代碼 都在這裏。

感謝閱讀 RecyclerView 系列 的第二篇文章。請繼續關注將來更多關於 RecyclerView 的內容。

若是您想了解更多關於 ListAdapter 的內容,請參考 官方文檔

相關文章
相關標籤/搜索