Synchronize RecyclerView with TabLayout using TabSync
Add synchronized scrolling to your Android app!
Edit: For people searching for an implementation for Jetpack Compose, TabSync Compose is out! You can now synchronize a TabbedListRow (or any index based composable) with a LazyColumn (or any LazyListState-based composables). Check out the same GitHub repository for details.
In this article, we’ll be discussing how to add a synchronizer between Android’s RecyclerView and TabLayout, and what are the use cases of such on mobile devices?
Most common case is when you’re trying to show a list of categories, each category has its own body, and that body has to be synchronized with an item of a TabLayout. This has been implemented in many today’s apps really, like Telegram in their emoji’s section for example.
As I’m working on our startup’s app, this synchronization had to be implemented. There weren’t any library or a built-in way that actually implements the synchronization, so I decided to build my own synchronizer, and now I’m publishing it as an open source library.
The expected behavior from the synchronization is that as you scroll through the RecyclerView’s items, the corresponding TabLayout items will be selected automatically, and vice-versa; when pressing on a TabLayout item, we want the RecyclerView to scroll to the corresponding item to view. Simple.. right? Well you might be surprised how easy it’ll be.
Let’s make a sample app to demonstrate the synchronization.
Prerequisites:
- You have a good knowledge of RecyclerView and how it works, and how nesting RecylerViews work.
- Understands the concept of TabLayout.
- A little bit of Kotlin; since this tutorial is written in Kotlin.
Follow these steps:
1- Make some models in order to display them as items in the RecyclerView:
We’ll be making an Item class that will have a simple String field:
And a Category class that will be nesting a list of items:
And therefore, our example list is going to be initialized like this:
And now we have a list of categories, each category has a list of items.
2- Create your xml file that contains your TabLayout and RecyclerView:
3- Initialize your RecyclerView and TabLayout adapters with their data:
The number of tabs will be equal to the number of categories we have initialized.
4- Add the library’s dependencies:
We will be using my library I used in my development app.
Add the maven central repository in root build.gradle:
Add dependency of the synchronizer library in your app’s build.gradle:
5- Create a TabbedListMediator object and pass the required parameters:
- The first two parameters are the RecyclerView and TabLayout that you wish to be synced.
- The third parameter is a list of indices of the RecyclerView items that you wish to be syncing with tabs.
Call attach on the mediator object to start syncing.
Note: that the third parameter must not provide a list of size of more than the tabs count of the TabLayout.
And the results are:
You may find it more smooth to look at if it smooth scrolls to the required destination, and for that case, you can add a fourth parameter to the constructor for smooth scrolling:
Results with smooth scroll on:
And that’s about it! Told you it will be easy!
Here’s a preview of the synchronization that has been tested in our in-production app FoodVibes:
Check out the GitHub repository of the library for the full code of the example, and other public methods provided by the library that you would probably need during your usage of this library, like re-attaching on certain scenarios, detaching to stop syncing, and more.
If you found this library useful, don’t forget to give the repo a star that would be much appreciated 😉
You can follow me on LinkedIn too:
Thanks for reading, and happy coding!
Edit 1: Thanks for the support I’ve seen from the community, and I’ve been witnessing many developers started using the library in their projects now! That’s great, and this kind of makes me want to extend the functionality of the library. Maybe add Jetpack Compost support, or syncing with grids? Let me know if you want to see it coming, or any other features get implemented!
Edit 2: TabSync Compose is out! You can now synchronize a TabbedListRow (or any index based composable) with a LazyColumn (or any LazyListState-based composables). Check the same repository for more information.