Adapting to ListAdapter

Meghan Mehta
Android Developers
Published in
3 min readDec 9, 2020

--

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.

Animation after adding an item.

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.

Diagram showing how areItemsTheSame() compares items.
Diagram showing how areContentsTheSame() compares items.

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.

--

--