PS:前两天有事,路过大学特意进去看了一下,熟悉的场景不熟悉的人,时隔几年,再也回不去了。
先看下该项目作者的介绍,MultiType 就是一个多类型列表视图的中间分发框架,它能帮助你快速并且清晰地开发一些复杂的列表页面,数据驱动视图,支持布局类型和 viewBinder 一对一及 一对多的关系绑定、面向接口编程,MultiType 将视图创建、数据填充的工作委托给了 ItemViewBinder,ItemViewBinder 对应要填充的数据类型 T 和 ViewHolder,后续不同的数据类型都需实现对应的 ItemViewBinder,项目地址如下:
https:
//github.com/drakeet/MultiType
将从以下几个方面学习 MultiType 的源码:
MultiTypeAdapter的使用
MultiTypeAdapter的register过程
MultiTypeAdapter的ViewHolder和数据填充
MultiTypeAdapter的使用
简单看下 MultiTypeAdapter 写法上与普通 Adapter 上的不同,如下:
1
// base
2adapter.register(TextItemViewDelegate())
3adapter.register(ImageItemViewDelegate())
4adapter.register(RichItemViewDelegate())
5
// One to many
6adapter.register(Data::
class).to(
7 DataType1ViewDelegate(),
8 DataType2ViewDelegate()
9).withKotlinClassLinker { _,
data ->
10
when (
data.type) {
11 Data.TYPE_2 -> DataType2ViewDelegate::
class
12
else -> DataType1ViewDelegate::
class
13 }
14}
15adapter.items = items
16recyclerView.adapter = adapter
17adapter.notifyDataSetChanged()
具体细节这里不再赘述,具体可以移步去前面地址查看。
MultiTypeAdapter的register过程
MultiTypeAdapter 的 register 过程主要是将 Type 类型添加到 MultiTypeAdapter 对应的集合中,以供后续使用,调用过程如下:
下面看下 MultiTypeAdapter一对多关系的register过程:
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 也是同理都是从添加的类型的集合中获取对应的委托的 ItemViewDelete 进行处理。
简单总结一下,上面这种使用方式就是将原来的 Recycler.Adapter 中的一些方法委托到了 ItemnViewDelegate 中,每种 Item 类型都添加到 MutableTypes 中的类型集合 types 中,具体实现则从委托的具体实现类中完成。
总结
简单总结下,将显示的 Item 的类型以 ItemViewBinder 的方式抽取出去,降低了不同 Item 的类型之间的耦合。使得可以随时添加 Item 的类型而无需修改 Adapter,只需添加新的 ItemViewBinder 的实现类即可。
作者提到的“一对多”的关系主要是同一个 Item 的类型对应多个布局实现,主要是学习作者代码思路,面向接口编程。个人理解 MultiTypeAdapter 相当于是对 RecyclerView.Adapter 的扩展而不是对其的封装,自己使用可以进一步封装。