Adapting to ListAdapter
This is the second in a series of articles which cover the fundamentals of creating and using RecyclerView
. If you already have a solid understanding of how to create a RecyclerView
, then carry on. Otherwise, consider starting with this post.
RecyclerView
is a great way to display a list of data items efficiently. For displaying a list of static data, the default adapter works great. However, in most use cases, RecyclerView
data is dynamic. Take a todo list app for example: new items are added, and completed items are removed. notifyItemInserted()
can insert new tasks at a specified index, but the issue comes when removing items. notifyItemRemoved()
is only useful if you have the position of the task you want to remove. It is possible to write code to get the position of the task to be removed and then call notifyItemRemoved()
, but this code can get messy. Calling notifyDataSetChanged()
is an option, but it redraws the entire view, even the unchanged parts, which is an expensive operation. ListAdapter
handles addition and removal without the need to redraw the entire view, and even animate those changes.
Another benefit of using ListAdapter
is that it comes with animations for when an item is added or removed. This provides a nice visual cue for the user to see the changes in the list. Animations are possible without ListAdapter
but they must be implemented by the developer and won’t have the same performance because the view will likely need to be redrawn along with being animated.
Split the difference
DiffUtil
is the secret ingredient that makes it possible for ListAdapter
to change the items in the list efficiently. DiffUtil
compares the new list with the old list to figure out what was added, moved, and removed and outputs a list of update operations that converts the first list into the second efficiently.
In order to identify new data, DiffUtil
requires you to override areItemsTheSame()
and areContentsTheSame()
. areItemsTheSame()
checks if two items are actually the same item. areContentsTheSame()
checks if two items have the same data.
In the Adapter
class add in a DiffUtil
object that overrides areItemsTheSame()
and areContentsTheSame()
.
Update the Adapter
class to inherit from the ListAdapter
class instead of RecyclerView.Adapter
. Pass in the DiffCallback
.
Updating the list
ListAdapter
gets data using a method called submitList()
, which submits a list to be diffed against the current list and displayed. This means you no longer have to override getItemCount()
because ListAdapter
manages the list.
In the Activity
class, call submitList()
on the Adapter
and pass in the data list.
In the Adapter
class, onBindViewHolder()
can now use getItem()
to retrieve items from the data list given a position.
That’s it! It only takes a few steps to convert your RecyclerView
to use ListAdapter
. Now your application can automatically get better performance and a better user experience by using ListAdapter
to update only those items that have changed.
Next Steps
The full code sample including ListAdapter
can be found here.
Thank you for reading the second installment in my RecyclerView
series! Stay tuned as I write about more RecyclerView
features.
If you want to learn more about ListAdapter
check out the documentation.