MultiTypeAdapter源碼分析

語言: CN / TW / HK

theme: jzman

我正在參加「掘金·啟航計劃」

PS:永遠向着我可以做的事情上努力。

先看下該項目作者的介紹,MultiType 就是一個多類型列表視圖的中間分發框架,它能幫助你快速並且清晰地開發一些複雜的列表頁面,數據驅動視圖,支持佈局類型和 viewBinder 一對一及 一對多的關係綁定、面向接口編程,MultiType 將視圖創建、數據填充的工作委託給了 ItemViewBinder,ItemViewBinder 對應要填充的數據類型 T 和 ViewHolder,後續不同的數據類型都需實現對應的 ItemViewBinder,項目地址如下:

將從以下幾個方面學習 MultiType 的源碼:

  1. MultiTypeAdapter的使用
  2. MultiTypeAdapter的register過程
  3. MultiTypeAdapter的ViewHolder和數據填充

MultiTypeAdapter的使用

簡單看下 MultiTypeAdapter 寫法上與普通 Adapter 上的不同,如下: kotlin // 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 中的一些方法委託到了 ItemnViewDelegate 中,每種 Item 類型都添加到 MutableTypes 中的類型集合 types 中,具體實現則從委託的具體實現類中完成。

總結

簡單總結下,將顯示的 Item 的類型以 ItemViewBinder 的方式抽取出去,降低了不同 Item 的類型之間的耦合。使得可以隨時添加 Item 的類型而無需修改 Adapter,只需添加新的 ItemViewBinder 的實現類即可。

作者提到的“一對多”的關係主要是同一個 Item 的類型對應多個佈局實現,主要是學習作者代碼思路,面向接口編程。個人理解 MultiTypeAdapter 相當於是對 RecyclerView.Adapter 的擴展而不是對其的封裝,自己使用可以進一步封裝,本文到此結束。