A Simple Way To Implement An On Boarding Slider Using ViewPager2 in Android

Carlos Daniel
The Startup
Published in
4 min readMay 4, 2020

Click here if you want to read the Spanish version

Well, new ViewPager2 API (released officially by the end of 2019) let us leverage its simple way of use to implement an on boarding screen using just 4 single classes and few code. As all you may know, ViewPager2 replaces ViewPager API (not receiving more active development support) and brings some interesting new features such as right-to-left support and Diffutils (is built on RecyclerView) among others. More details and comparison with ViewPager here in the official DAC documentation.

Implementing a Basic Swipeable Screen

The easiest way to see this working is creating an on boarding screen, in which we let the user know some important information of the app while swiping among different pages, but it is actually a single fragment.

This is the app we are going to implement:

On Boarding Slider

Let’s start creating a new project with an empty Activity and adding the dependency for ViewPager2 and Glide (the images we are gonna use will be loaded using Glide lib):

The app shows a single Fragment in OnBoardingActivity, and the way it is displayed is through the ViewPager2, which in turn uses a FragmentStateAdapter. This is the key, let’s see how…

on_boarding_activity layout as can be seen, uses a ViewPager2 widget covering the entire screen. Also using a constraint layout we set the buttons, indicators (circles) and bottom text fixed to the bottom of the screen. Then the content that we are going to slide will be placed within the ViewPager2.

To accomplish this, we need first to create a custom FragmentStateAdapter to wire with the ViewPager widget, which takes two parameters. A reference to the Activity which hosts the adapter, and an Int that tells the adapter the number of items it’ll show. Also we need to override the methods getItemCount() and createFragment(). The first to tell the adapter the number of items of the slider and the second to create an instance of the Fragment for a given position:

Now, the fragment layout looks like this (an image and some informative texts):

And the OnBoardingFragment in which we bind all the data to each page in the pager looks as follows. We must take into consideration that this particular example takes all the data locally from resource strings and raw, but this can be escalated to be gotten from an API or even a local DB.

The most important thing of the Fragment class above is how we can get the position from the adapter, then pass it to the fragment as a bundle param and it’s gonna be used to get the data from resources. This is how we wired the fragment and the adapter.

Now to wire the Fragment with the Activity through the ViewPager, we need simply to listen for page changes. ViewPager2 uses an abstract class, OnPageChangeCallback, which provides an empty implementation for three methods. This way, we only need to override the methods we need, in this case, onPageSelected().

Then we create a onBoardingPageChangeCallback object, that needs to be registered in the ViewPager (binding.onBoardingViewPager.registerOnPageChangeCallback) and to avoid memory leaks, has to be unregistered when the Activity is being destroyed (binding.onBoardingViewPager.unregisterOnPageChangeCallback)

The local method updateCircleMarker() has the responsibility of wiring the position of the pager with the indicator to visually distinguish and follow the change.

UI Testing the ViewPager

Well, this is easy because it doesn’t have anything different than a ActionView’s swipe() method to test the sliding. All tests over OnBoardingActivity screen are gonna be launched within an ActivityScenarioRule<>, which is a rule that launches a given activity before the test starts and closes after the test. We need to add a couple of dependencies to the app’s build.gradle file:

After sync, and create an ActivityScenarioRule object within the Android Test file, we are gonna get this error message:

Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6

This can be easily fixed adding this line to app’s build.gradle file within android{…} block to tell Kotlin compiler in AS to do it using an specific version of the JDK:

kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8
}

Finally our UI test code class looks like this:

… and this is all, this is the repo that you can use and share with others. Also take into consideration that this is a single use of the ViewPager2 API, but you can also customize its use either using a vertical swipe, adding a TabLayout or trying the RTL support among other interesting stuff.

--

--

Carlos Daniel
The Startup

Android & Flutter Developer. GDE for Android & Mobile Engineer.