What’s the difference between a ListView and a RecyclerView?

As Android Developers we are able to implement scrolling list in a couple of ways which mostly depends on what we really need to do. The most popular ones is to use a ListView or a RecyclerView.
The first one is a good old widget which is in Android SDK since the API 1. Until Android Lollipop we used mostly this one and it wasn’t that bad — the API is mostly intuitive. Unfortunately it allows us to create just the vertical-scrolling list of elements and to make that list scrolling smoothly we have to remember to do it in a proper way. Moreover the ListView class is a bit too heavy — it has a lot of responsibilities. Whenever we had to handle the list, in some way configure it, the only way to do this it through the ListView object or inside the adapter.
Nowadays we use the RecyclerView. As I’ve mentioned, it was introduced with the Android Lollipop and it was a game changer. A lot of things that we hate in the ListView was fixed or changed in the RecyclerView. It’s more efficient by default, layouting is separated and we have more possibilities over the data set inside the adapter.
If you want to know more about them you can take a look at my articles which show how to implement the ListView and the RecyclerView.
I’ll describe the most crucial differences between these two below.
ViewHolder
The ViewHolder pattern allows us to make our list scrolling smoothly. It stores list row views references and thanks to that calling findViewById()
method is happening just a couple of times, but not for all data set and on each bind view.
The RecyclerView’s adapter forces us to use ViewHolder pattern. The creating part (inflating the layout and finding views) and updating the views is split into two method — onCreateViewHolder()
and onBindViewHolder()
.
The ListView on the other hand by default doesn’t give us that kind of protection so without implementing the ViewHolder pattern inside getView()
method, we’ll end with inefficient scrolling in our list.
LayoutManager
The LayoutManager takes responsibility for layouting row views. Thanks to that RecyclerView don’t have to think about how to position the row view. This class gives us opportunity to choose the way that we want to show the row views and how to scroll the list. For example if we want to scroll our list vertically or horizontally we can choose LinearLayoutManager. For grids more suitable is GridLayoutManager.
Previously, with the use of the ListView, we was able to create just the vertical-scrolling list, so it wasn’t that flexible. If we wanted grids in our list we had to choose the other widget for that — GridView.
ItemDecoration
Duty of the ItemDecoration is simple in theory — add some decorations for the list row views — but in practice it’s that simple to implement if we want to create a custom one. Then we should extend ItemDecoration class and implement our solution. For example the RecyclerView list by default has no dividers between rows — it’s consistent with the Material Design guidelines. However if we want to add divider for some reason, we can use DividerItemDecoration and add it to the RecyclerView.
In case we use the ListView we have to figure out rows decorations by ourself. There is not helper class like ItemDecoration for this widget.
ItemAnimator
The last but not least RecyclerView’s component that I want to mention is ItemAnimator. As we can expect it’s handling row views animations like list appearance and disappearance, adding or removing particular view and so on. By default RecyclerView’s list animations are nice and smooth. Of course we can change that by creating our own ItemAnimator which is also not that easy. To make it easier we should extend the SimpleItemAnimator class and implement the methods that we need (just add animations on a ViewHolder’s views).
To be honest, implementing animations on the ListView was a pain in the ass. Again, we had to figure out how we want to handle them. Nothing nice. I’m glad it’s ended.
Notifying adapter
We have a couple of cool notifiers on the RecyclerView’s adapter. We still are able to use notifyDataSetChanged()
but there are also ones for particular list element like notifyItemInserted()
, notifyItemRemoved()
or even notifyItemChanged()
and more. We should use appropriate ones for what is actually happening so the proper animations will fire.
Using ListView we was able to use just notifyDataSetChanged()
on the adapter and then the rest we had to handle ourselfs, again.
Conclusion
The ListView served us for a long time. We was able to cover most on the cases. But user needs are different now, more challenging. List designs became more and more complex and the ListView wasn’t helping to handle them. Material Design brought another changes — beautiful but complex.
Fortunately the RecyclerView was introduced and a lot of problems were solved. It’s more efficient by default, animations are simpler, layouting is easier and the API is much nicer.
So if you ever wonder which one you should choose, your first thought should be definitely the RecyclerView.