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() checks if two items are actually the same item.
areContentsTheSame() checks if two items have the same data.
Adapter class add in a
DiffUtil object that overrides
Adapter class to inherit from the
ListAdapter class instead of
RecyclerView.Adapter. Pass in the
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
ListAdapter manages the list.
Activity class, call
submitList() on the
Adapter and pass in the data list.
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.
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
If you want to learn more about
ListAdapter check out the documentation.