Recycler View Internals — I: Birth Of ViewHolder
Can you Implement your own RecyclerView from scratch? You will never say no again.
officially published on :
featured on :
We all have been working with RecyclerViews
for way long and are very familiar using its API to display our list efficiently, but many have just touched its surface on a very high level, few of us have dug deep into it and tried to figure how internally it works. I’m one of the same, I have a generalised idea of what might be happening but I never looked at its implementation from Android open source project (AOSP) but before I do that I wanted to figure out how others in the community have explored it.
After some poking around I was told by many developers to follow a talk on RecyclerViews ins and outs — Google I/O 2016 for getting an idea of what RecyclerViews
are doing under the hood. If you haven’t seen it yet, I would highly recommend you to watch this video, in-fact bookmark it you will be visiting it a lot in your android career.
It actually does a pretty nice job explaining various components of RecyclerView
and those diagrams are ❤️ . But that is also the problem with the video, even though there are so many details in the video but everything is just in form of diagrams and flows. We don’t see any code examples or implementations that we can relate to understand the Recycler view more deeply.
Since that is not done, and I don’t want to hurt my soul by looking into AOSP, I have used decided to use my big 🧠 to implement these diagrams into workable code.
This video is divided into 4 parts:
- Birth Of
ViewHolder
- Adding View to UI
- Death of
ViewHolder
- Animation on
RecyclerView
Operation
From the title of the article, you must have figured that I will be covering the first section i.e Birth Of ViewHolder
before that let's look into RecyclerView
Components.
RecycleView Components
The first half of the video introduced us to the various components of the RecyclerView
. Let’s make our classes accordingly to it.
p.s. In comments I have added responsibilities of each component.
You can clearly see Adapter
are expressed as View Providers but do lot more things than that like
- Binding data,
- Notify data changes,
- Recycle recovery,
- Working with Multiple view types and more
Let's get started with the Implementation
Birth Of View Holder
There are three possible scenarios encountered in flow of creation of ViewHolder
- View Cache Success
- View Cache Failed, Recycler Pool Success
- View Cache Failed and Recycler Pool Fails
View Cache Success ✅
In the first section, we learn that the LayoutManager
requests RecyclerView
for the View at a Position. Recycler is a very fast component because it tries to cache data on each step.
So instead of going through an expensive cycle of creating a new view, it will try to return it from the cache.
The scenario in which Recycler’s View Cache
Pass i.e it will return cached View
instance immediately satisfying layout manager request.
The first flow use case results in the following component interaction,
Component interactions :
[Layout Manager] ---- getViewForPosition ----> [Recycler View]
[Recycler View] ---- getViewForPosition ----> [View Cache]
[View Cache] ---- cache returns View ✅ ----> [Recycler View]
[Recycler View] ---- returns View ----> [Layout Manager]
You can follow the sequence to see flow of control.
In Program this translates to :
If you don’t know what is TODO()
checkout my article from here :
View Cache Failed ❌, Recycler Pool Success ✅
When View Cache
Fails to return a view for a given position, it goes through series of steps to create a new view.
Let’s break these steps down :
RecyclerView
after receiving failure fromViewCache
, askAdapter
to returnViewType
for the position.- After receiving
ViewType
,RecyclerView
checks itsRecyclerPool
to see if the cache ofViewHolder
is present or not. - If
RecyclerPool
Passes i.e. returns aViewHolder
, thenRecyclerView
takes thatViewHolder
to theAdapter
, and tries tobind
new data to it. - Once bound
RecyclerView
takes ViewHolder’sView
and return it to theLayout Manager
.
Told you View Creation is an expensive task. Let’s see component interaction in this process :
Component interactions :
[Layout Manager] ---- getViewForPosition ----> [Recycler View]
[Recycler View] ---- getViewForPosition ----> [View Cache]
[View Cache] ---- cache returns null ❌ ----> [Recycler View]
[Recycler View] ---- getViewType ----> [Adapter]
[Adapter] ---- ViewType ----> [Recycler View]
[Recycler View] ---- getViewHolderByType ----> [RecyclerPool]
[RecyclerPool] ---- ViewHolder ----> [Recycler View]
[Recycler View] ---- bindViewHolder ----> [Adapter]
[Adapter] ---- View ----> [Recycler View]
[Recycler View] ---- View ----> [Layout Manager]
You can follow the sequence to see flow of control :
In Program this translates to :
IMO, API is coming out nicely designed just by following the diagrams in the Video.
View Cache failed ❌, Recycler Pool failed ❌
RecyclerPool
is a cache of Viewholders
, what will happen if the Viewholder
you are looking for isn’t there in cache?
Let’s see :
- If
RecyclerPool
fails, it will returnnull
toRecyclerView
RecyclerView
will go toAdapter
and request it to create newViewHolder
from theViewType
.Adapter
will create a newViewHolder
andbind
it with thedata
for the requestedposition
.Adapter
will returnViewHolder
toRecyclerView
andRecyclerView
return theView
back toLayoutManger
.
So only one step is extra when RecyclerPool
fails, the Adapter
will create new Viewholder
and binds
the data.
Let's see the component interaction :
Component interactions :
[Layout Manager] ---- getViewForPosition ----> [Recycler View]
[Recycler View] ---- getViewForPosition ----> [View Cache]
[View Cache] ---- cache returns null ❌ ----> [Recycler View]
[Recycler View] ---- getViewType ----> [Adapter]
[Adapter] ---- ViewType ----> [Recycler View]
[Recycler View] ---- getViewHolderByType ----> [Recycler Pool]
[Recycler Pool] ---- returns ViewHolder ❌ ----> [Recycler View]
[Recycler View] ---- createViewHolder ----> [Adapter]
[Adapter] ---- bindViewHolder ----> [Adapter]
[Adapter] ---- ViewHolder ----> [Recycler View]
[Recycler View] ---- View ----> [Layout Manager]
Follow the sequence for flow of control :
In Program this translates to :
Adapter
and ViewHolder
is of an abstract type, if you want to see how will their implementation looks like check the code below 👇:
Conclusion
Alrighty, the design logically appears to be correct till the point where the birth of the view holder is explained in the video.
Hope you like my implementation, if you don’t please suggest improvement in my repository where I’m experimenting with the code :
In the second part of the article, we will continue with how the view of the layout manager is added to the UI. So stay tuned.
If you like my content and want to see more, click right here to see more 👇
Until next time, Happy Hacking! 👨🏻💻
Enjoy the article? a clap is much appreciated if you enjoyed it.