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 :

  1. RecyclerView after receiving failure from ViewCache , ask Adapter to return ViewType for the position.
  2. After receiving ViewType, RecyclerView checks its RecyclerPool to see if the cache of ViewHolder is present or not.
  3. If RecyclerPool Passes i.e. returns a ViewHolder, then RecyclerView takes that ViewHolder to the Adapter, and tries to bind new data to it.
  4. Once bound RecyclerView takes ViewHolder’s View and return it to the Layout 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 :

  1. If RecyclerPool fails, it will return null to RecyclerView
  2. RecyclerView will go to Adapter and request it to create new ViewHolder from the ViewType.
  3. Adapter will create a new ViewHolder and bind it with the data for the requested position.
  4. Adapter will return ViewHolder to RecyclerView and RecyclerView return the View back to LayoutManger.

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 👇

https://chetangupta.net/

Until next time, Happy Hacking! 👨🏻‍💻

‌Enjoy the article? a clap is much appreciated if you enjoyed it.

--

--