PS: I had something to do the other day, so I went to the university to take a look. Familiar scenes, unfamiliar people. It's been a few years, and I can never go back.
First, let's take a look at the introduction of the project author. MultiType is an intermediate dispatch framework for multi-type list views. It can help you quickly and clearly develop some complex list pages. It is data-driven and supports one-to-one and one-to-many relationship bindings between layout types and viewBinders. MultiType delegates the work of view creation and data filling to ItemViewBinder. ItemViewBinder corresponds to the data type T and ViewHolder that need to be filled. Subsequent different data types need to implement the corresponding ItemViewBinder. The project address is as follows:
We will learn the source code of MultiType from the following aspects:
- Usage of MultiTypeAdapter
- Registration process of MultiTypeAdapter
- ViewHolder and data filling of MultiTypeAdapter
Usage of MultiTypeAdapter#
Let's take a look at the difference in writing between MultiTypeAdapter and a regular Adapter, as shown below:
// 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()
The specific details are not elaborated here. You can go to the previous address to check.
Registration process of MultiTypeAdapter#
The registration process of MultiTypeAdapter is mainly to add the Type to the corresponding collection of MultiTypeAdapter for later use. The calling process is as follows:
Let's take a look at the registration process of one-to-many relationship in MultiTypeAdapter:
As shown above, it returns to the registration process of one-to-one relationship.
ViewHolder and data filling of MultiTypeAdapter#
In the previous section, MultiTypeAdapter delegates some methods of RecyclerView.Adapter to the specific implementation of ItemViewBinder, and adds the specific ItemViewBinder, Linker, and Class information of data type T to the type collection in MultiTypeAdapter in the form of Type. The item type, ViewHolder creation, and data filling all need to be implemented by the specific subclass of ItemViewBinder. Let's explore this process in detail.
getItemViewType#
getItemViewType is used to return the view type of the item. In MultiTypeAdapter, the view type index returned by getItemViewType is the index of the corresponding Type in MutableTypes. The calling process is as follows:
From the above, it can be seen that the final index of the view type returned is index+linker.index. From the source code, it can be seen that in the case of one-to-one, DefaultLinker is used, and its default index is 0. Therefore, the final index of the view type returned is the index of the corresponding Type in MutableTypes.
onCreateViewHolder#
onCreateViewHolder is used to create a ViewHolder based on the layout file. The specific calling process is as follows:
onBindViewHolder#
onBindViewHolder is similar to onCreateViewHolder, which also obtains the corresponding delegated ItemViewDelete from the collection of added types.
In summary, the above usage allows the types of displayed items to be extracted as ItemViewBinder, reducing the coupling between different types of items. It allows adding item types at any time without modifying the Adapter, just by adding new implementations of ItemViewBinder.
The "one-to-many" relationship mentioned by the author mainly refers to multiple layout implementations corresponding to the same item type. It is mainly to learn the author's code ideas and program in an interface-oriented manner. Personally, I think MultiTypeAdapter is an extension of RecyclerView.Adapter rather than an encapsulation. It can be further encapsulated for personal use.