We developers are always finding a way to an easiest and less manageable task.At the time of designing some ui, we have to manage different types of view in a single recyclerview which is somehow becoming difficult for us. It is time consuming too. It will be great for us if this case is handled very easily without much complications.
Here is good news for us.
To help us android has come up with a new concept of merging data adapters. Recently they have a new release of recyclerview:1.2.0-alpha02 package. This package has a new class named MergeAdapter as the name says it allows you to merge multiple data adapters in a single recyclerview. So now we can easily maintain our data source differently instead of combining in a single adapter.
So let us start with the example. Suppose, you have been given the following screen to design and manage progress along with hide and show views like below. These all can be done in a single recyclerview. Let’s see how it will work. We will understand this concept with the help of this example.
What is MergeAdapter
MergeAdapter allows us to unite data from multiple adapters in a series. In our example, we have 3 different adapters. One is for title & image, second is for list of food and third is for progress along with a quote.
private val headerAdapter = HeaderAdapter()
private val foodListAdapter = FoodListAdapter()
private val footerAdapter = FooterAdapter()
val mergeAdapter = MergeAdapter(headerAdapter, foodListAdapter, footerAdapter)
rv.adapter = mergeAdapter
Data from all three adapters will be displayed sequentially in a recyclerview. This way you can manage your logic separately, there is no need for any logic mixup. For example you can manage progress of the bottom view in it’s own adapter instead of combining it with others.
Points to keep in mind
- MergeAdapter will call notifyDataSetChanged() method every time when we are calling notifyDataSetChanged() of adapters which are part of mergeAdapter. So better use ListAdapter to avoid calling this method.
- Usually we use one view holder per adapter. But if in case you want to use one view holder for more then one adapter while using mergeAdapter then you have to pass config in the constructor like this
123val configBuilder = MergeAdapter.Config.Builder()configBuilder.setIsolateViewTypes(false)val mergeAdapter = MergeAdapter(configBuilder.build(),headerAdapter, foodListAdapter, footerAdapter)
- We always use ViewHolder.getAdapterPosition() method to find position of viewHolder in the adapter. As now we are using MergeAdapter, use ViewHolder.getBindingAdapterPosition() method. If you are reusing viewHolders and want to get the last adapter which is bound then use ViewHolder.getBindingAdapter() method.
- If you want to use the same adapter multiple times in a recyclerview then you can create multiple instances of the same adapter and pass them in the constructor of mergeAdapter.
- It is good practice to define your logic in different adapters.
How to work with MergeAdapter
- You can pass list of adapters instead of individual adapters to the constructor of mergeAdapter like this,
12val adapterList = listOf<RecyclerView.Adapter<out RecyclerView.ViewHolder>>(headerAdapter, foodListAdapter, footerAdapter)val mergerAdapter = MergeAdapter(adapterList)
- Coming back to the example, if you want to add adapter dynamically at run time as I have added offer section on click of button then this can be done like this,
12val offerAdapter = OfferAdapter()mergeAdapter.addAdapter(offerAdapter)
- This will add offerAdapter at the last position in the list. If you want to add adapter, let’s say at second position in the list, then you have to specify index like this,
- Likewise, if you want to remove adapter from the list
- If you want to get total number of item count in a recyclerview merging all the adapter use,
- If you want to get list of adapter present in recyclerview use,
So, working with multiple views in a recyclerview is very easy now. MergeAdapter is helping us in many ways to reduce our burden.
Hope you get something new from this article.Have a wonderful day ahead.