RecyclerView — More Animations with Less Code using Support Library ListAdapter
ListAdapter is a new class bundled in the 27.1.0 support library and simplifies the code required to work with
RecyclerViews. The end result is less code for you to write and more recycler view animations happening for free.
Why is it great? It’s great because it automatically stores the previous list of items and utilises
DiffUtil under the hood to only update items in the recycler view which have changed. This typically means better performance as you avoid refreshing the whole list, and nicer animations because only items which change need to be redrawn.
Let’s say you have this class which represents a user’s tasks in a todo app. This example happens to be a Room entity but that’s not required.
Adapter — The Old Way
To display a list of tasks in a recycler view, previously you would have written your adapter to inherit from
RecyclerView.Adapter<ViewHolder> and it might have looked something like this.
The biggest problem this code has is that it only handles adding new tasks and wouldn’t cope with deletions or edits. If we wanted to easily handle those cases as well, we could cheat and use
notifyDataSetChanged() but we’d lose the nice animations. To handle them properly, we’d need to implement
DiffUtil which is a bit more work.
ListAdapter is built on top of
DiffUtil meaning it handles some of the diffing logic for you. If you aren’t familiar with
DiffUtil, it was created to further encourage developers to let the
RecyclerView only update the contents which changed; resulting in better performance when items are inserted, updated or deleted.
If you are still using
notifyDataSetChanged() then you are forcing the entire list to be redrawn and therefore not allowing Android the chance to show nice visual cues to the user as to what exactly just changed. Instead of reloading the entire list, you can use methods like
notifyItemRemoved. These result in lovely animations but working out which method to invoke manually is non-trivial.
DiffUtil helps you by calculating which methods to invoke out of
DiffUtil is great but it still requires a bit of boilerplate to implement.
Adapter — The New Way
To make use of the new
ListAdapter we would update the existing adapter so that it inherits
ListAdapter and pass in the type of item it will show —
Task in this case — as well as the
In the constructor, you need to provide a
DiffUtil.ItemCallback which is a slimmed down version of the
DiffUtil.ItemCallback requires you to implement two functions:
areItemsTheSame hands you two items and asks you if they fundamentally represent the same object. In my case, I have a unique ID I can use to compare. If the IDs match, then I know the items are the same even if some of their other fields may differ.
areContentsTheSame hands you two items again. This time, though, it asks you if the two items have the same content. If you decide your items do have the same content, then no redraw and no animation are required; you are already displaying the object and you are saying that nothing has changed.
However, if you decide the contents are not the same, then the item will be redrawn on screen.
Shiny New Adapter
It’s not much different from the old adapter. We have a new superclass, we’ve deleted the list of items we were storing previously and we’ve ditched the manual
addTask method we had before. In the constructor, we pass in an instance of our
Updating the Adapter
Whenever you need to update the adapter, you can provide the new list of items to it using the
You aren’t tied into using
LiveData and so long as you can obtain an updated list, you can make use of
But it sure is nice when you do use
LiveData 😎. Whenever you are notified of a change, just submit that straight to the adapter and it’ll take care of the rest.
RecyclerView is great. But it’s better when animations are shown as its contents are changed. You can cheat and update the entire list every time something changes but that’s usually not necessary. You can achieve better performance and those nice animations yourself with a bit of code.
Or you can make use of
ListAdapter. The end result is less code, more animations and happier users 😃.