PS:前兩天有事,路過大學特意進去看了一下,熟悉的場景不熟悉的人,時隔幾年,再也回不去了。
先看下該項目作者的介紹,MultiType 就是一個多類型列表視圖的中間分發框架,它能幫助你快速並且清晰地開發一些複雜的列表頁面,數據驅動視圖,支持佈局類型和 viewBinder 一對一及一對多的關係綁定、面向接口編程,MultiType 將視圖創建、數據填充的工作委託給了 ItemViewBinder,ItemViewBinder 對應要填充的數據類型 T 和 ViewHolder,後續不同的數據類型都需實現對應的 ItemViewBinder,項目地址如下:
將從以下幾個方面學習 MultiType 的源碼:
- MultiTypeAdapter 的使用
- MultiTypeAdapter 的 register 過程
- MultiTypeAdapter 的 ViewHolder 和數據填充
MultiTypeAdapter 的使用#
簡單看下 MultiTypeAdapter 寫法上與普通 Adapter 上的不同,如下:
// base
adapter.register(TextItemViewDelegate())
adapter.register(ImageItemViewDelegate())
adapter.register(RichItemViewDelegate())
// One to many
adapter.register(Data::class).to(
DataType1ViewDelegate(),
DataType2ViewDelegate()
).withKotlinClassLinker { _, data ->
when (data.type) {
Data.TYPE_2 -> DataType2ViewDelegate::class
else -> DataType1ViewDelegate::class
}
}
adapter.items = items
recyclerView.adapter = adapter
adapter.notifyDataSetChanged()
具體細節這裡不再贅述,具體可以移步去前面地址查看。
MultiTypeAdapter 的 register 過程#
MultiTypeAdapter 的 register 過程主要是將 Type 類型添加到 MultiTypeAdapter 對應的集合中,以供後續使用,調用過程如下:
下面看下 MultiTypeAdapter 一對多關係的 register 過程:
如上第 10 步又換回到了一對一的註冊流程上了。
MultiTypeAdapter 的 ViewHolder 和數據填充#
上一小結 MultiTypeAdapter 主要是將原本 RecyclerView.Adapter 中的一些方法委託到了 ItemViewBinder 具體的子類實現中,並將具體的 ItemViewBinder、Linker、數據類型 T 的 Class 信息以 Type 的形式添加到 MultiTypeAdapter 中的類型集合中,其 Item 類型、ViewHolder 創建、數據填充都需通過具體的 ItemViewBinder 的子類實現,下面將詳細探究這一過程。
getItemViewType#
getItemViewType 用來返回 Item 的視圖類型,MultiTypeAdapter 中的 getItemViewType 返回的視圖類型索引是 MutableTypes 中對應 Type 的索引,調用流程如下:
從上面可知最終返回的視圖類型的索引為 index+linker.index,從源碼可知在一對一的情況下使用的是 DefaultLinker,其默認的 index 是 0,所以最終返回的視圖類型的索引就是 MutableTypes 中對應 Type 的索引 index。
onCreateViewHolder#
onCreateViewHolder 用來根據佈局文件創建生成 ViewHolder,具體調用流程如下:
onBindViewHolder#
onBindViewHolder 也是同理都是從添加的類型的集合中獲取對應的委託的 ItemViewDelete 進行處理。
簡單總結一下,上面這種使用方式就是將原來的 Recycler.Adapter 中的一些方法委託到了 ItemViewDelegate 中,每種 Item 類型都添加到 MutableTypes 中的類型集合 types 中,具體實現則從委託的具體實現類中完成。
總結#
簡單總結下,將顯示的 Item 的類型以 ItemViewBinder 的方式抽取出去,降低了不同 Item 的類型之間的耦合。使得可以隨時添加 Item 的類型而無需修改 Adapter,只需添加新的 ItemViewBinder 的實現類即可。
作者提到的 “一對多” 的關係主要是同一個 Item 的類型對應多個佈局實現,主要是學習作者代碼思路,面向接口編程。個人理解 MultiTypeAdapter 相當於是對 RecyclerView.Adapter 的擴展而不是對其的封裝,自行使用可以進一步封裝。