Why you should be using the new and improved RecyclverView ListAdapter in Android
Displaying a list of items in a list with a RecyclerView is a very common pattern in Android Development. So much so that most developers do not go to the trouble of writing the adapters from scratch anymore. Simply copy and paste a previous one and edit as needed. Better yet, if you using Kotlin (and you should), you can use a template such as this one I wrote here. So, in the olden days of Android, you would extend RecyclerView.Adapter< MyViewHolder> and then go ahead to implement the required three methods. I will not go into the details of that but there were two annoying things you had to do namely:
- Implementing the getItemCount() method and returning the size of your list. Additionally, this meant having a list variable, which would be submitted in the constructor of the adapter or through a convenience method in your adapter class.
- The ever expensive notifyDataSetChanged() method. Do not even get me started on the number of times I forgot to call this method.
As opposed to those olden days, Android now has the new and improved ListAdapter. According to the official documentation, it is: RecyclerView.Adapter base class for presenting List data in a RecyclerView, including computing diffs between Lists on a background thread. This new adapter updates itself with some awesome animations once there are changes in your underlying list. What this means is that calling the notifyDataSetChanged() method is something you do not have to worry about anymore. The following is a sample implementation of the adapter.
Note that getting the item of your list is now as simple as calling the getItem()method passing in the position, which is already supplied in your onBindViewHolder() method as follows:
val movie = getItem(position)!!
Another thing to note is that the class extends the ListAdapter<POJO, PojoViewHolder>. This actually makes sure the getItem(position)!! method returns your POJO. Additionally, we do not have a list that we pass into our constructor. So how does the adapter know about the list?
This is how the adapter knows about your list. So in your activity/fragment, assuming you are using the MVVM pattern, you will have something like the following:
Note that your liveData object in your ViewModel will hold a list of type POJO. So once you observe that list in the UI, then you simply call:
If there is a list already displayed, then a diff will be computed to notify items on the main thread.
What is this DiffUtil?
You will notice the above class and you may be wondering what it does. According to the official documentation:
DiffUtil is a utility class that can calculate the difference between two lists and output a list of update operations that converts the first list into the second one. It can be used to calculate updates for a RecyclerView Adapter
DiffUtil is the class that actually removes the need for calling the notifyDataSetChanged() method. We have overridden two of its methods namely areItemsTheSame(oldItem: Pojo, newItem: Pojo) and areContentsTheSame(oldItem: Pojo, newItem: Pojo). The first method simply checks if the two objects are the same (for example based on ids) while the second checks if the data between the two objects is the same.
Without getting into the details too much, you now have a basic understanding of why you should make the switch to the ListAdapter. In the next part of this article, I will talk about how you can use the adapter with DataBinding to remove that annoying boilerplate code. In the meantime, happy coding and stay safe!