Migrating to ViewPager2

Volodymyr Buberenko
ProAndroidDev
Published in
4 min readJan 9, 2020

--

Photo by Ergita Sela on Unsplash

ViewPager is a well-known citizen in lots of Android apps since its first appearance. We use it for setup wizards, introduction screens, books and tons of other scenarios with customizations of all kinds.

Yet, it wasn’t ideal and developers saw some room for improvement. So after some back and forth Google released a reworked version and named it ViewPager2.

The main purpose of this article is to show an example of a real project migration to ViewPager2, without doing a deep comparison between versions. However, I can’t move further without highlighting the main changes:

  • ViewPager2 now based on a RecyclerView, so we should get better efficiency.
  • Vertical orientation support, thanks to LayoutManagers from RecyclerView.
  • There is only one type of adapter now called FragmentStateAdapter, which corresponds to FragmentStatePagerAdapter from old ViewPager.
  • DiffUtil for dataset changes in views.
  • RTL support out of the box.
  • ItemDecoration from RecyclerView is also available.
  • MarginPageTransformer and CompositePageTransformer should ease the application of custom page transformations.
  • With LinearSnapHelper and custom PageTransformer it is much easier to create a carousel view with next and previous items partially visible.

If it is not enough and you would like to read an in-depth overview, I will add some links at the end of this article.

Candidate for migration

To make this guide not too abstract I decided to pick a real project with ViewPager on board and migrate it. This time it is an open-source library for network requests/responses and Throwable inspection called Chucker.

Activity with ViewPager in Chucker

This tool actually has 2 screens with ViewPager and I migrated both, but for this guide I will show you only the one with 3 tabs on it.

The migration

First step is to add a new dependency — yes, the new version has its own dependency. And yes, ViewPager2 is a part of AndroidX.

Layout file update

Next step is to replace the component in a layout XML file. In most cases it requires only a change of XML tag:

Change in layout XML file

Adapter update

Now it is time to update the adapter:

Adapter before migration
Adapter after migration

Since the target Activity used FragmentStatePagerAdapter, we need to switch to FragmentStateAdapter, because it is the only option for Fragments adapter now. This fact might confuse those, who remember that old ViewPager had 2 types of adapters. But no worries here - FragmentStateAdapter in ViewPager2 behaves just like FragmentStatePagerAdapter in old ViewPager.

If you used PagerAdapter to swipe through views, you have to switch toRecyclerView.Adapter when migrating to ViewPager2. Source

If you checked changes above carefully, you should have seen that there is no getPageTitle() function in the updated adapter and this is not a mistake. In ViewPager2 interaction with TabLayout implemented in a new way, which you will see below in Activity update.

Another thing to note here is that there are 3 constructors for FragmentStateAdapter in ViewPager2:

Google recommends using the first two. I suppose these recommendations are to save developers from issues with wrong Lifecycle objects passed.

Host view update

Finally, let’s change activities to use updated adapters. For the sake of clarity, I omitted all unrelated functions from gists:

Activity before migration
Activity after migration

You might see that instead of addOnPageChangeListener() we now use registerOnPageChangeCallback(). Despite the updated name, both functions are basically the same.

What is more interesting is a code block with TabLayoutMediator(). This class takes TabLayout and ViewPager2 as parameters and handles the synchronization of their states. To do so, it listens to OnPageChangeCallback from ViewPager2 and to OnTabSelectedListener from TabLayout.

Also, this is the place where you should set a tab name depending on the current position. Such approach is much better than the old one where adapter had a link to Context just to be able to set a tab title.

And this is it. We just migrated to a new ViewPager without too much hassle or issues. As you might see there are not that many changes and the component itself is pretty stable.

So don’t hesitate to migrate your projects to enjoy the efficiency and flexibility of ViewPager2.

Thanks for reading. If you find this topic interesting, don’t forget to clap and write responses. In case of readers being interested, I might create another article about ViewPager2, this time with DiffUtil usage example.

Full PR of Chucker migration can be found here.

Some useful additional info on the topic:

--

--