Android Infinite scrolling ViewPager2

Ashish Pandey
5 min readAug 28, 2021

--

You might be aware of the fact that Google has updated the old ViewPager library to the newer ViewPager2 with some cool exciting advantages with even less code. And the most important reason for you to migrate to ViewPager2 if you haven’t already is that its receiving active development support. Also, the other benefits include:

  • Vertical orientation support
  • Right-to-left support
  • Modifiable fragment collections
  • DiffUtil

So, there’s no reason for you to do migrate. Moving ahead, here we are making an app with multiple views on a ViewPager2 capable of infinite scrolling behavior.

Final Output | Inifinite ViewPager2

The Problem

See, ViewPager2 is built on RecyclerView. So we normally use RecyclerView Adapters for organizing the list data on the Viewpager2 for the case of sliding views. And normally we submit the list of the data that we would like to show on the ViewPager slider.

This can only make you slide from the very first view till the last view and that’s it. You can’t scroll backward to the last view from the first view and forward from the last view to the first view. This problem can make it cumbersome for the user to scroll through views on the ViewPager2.

Three views on the ViewPager2 only able to scroll like shown by arrows

So, our target is to make the user able to scroll directly from the first view to the last view with backward scroll and from the last view to the first view with forward scroll.

Three views on the ViewPager2 able to scroll in a circular fashion

The Solution

So basically to make a workaround for infinite scrolling views on the ViewPager2 we have to go like

  • First, add a fake first view after the actual last view and also add a fake last view before the actual first view.
  • When the user is on fake last view, replace it with the actual last view and when the user is on the fake first view, replace it with the actual first view.

The Coding Process

Firstly add a ViewPager2 in your XML Layout of your Activity, for instance in activity_sample.xml

<androidx.viewpager2.widget.ViewPager2
android:id="@+id/infiniteViewPager"
android:layout_width="match_parent"
android:layout_height="200dp" />

ViewPager item data class

Then create a sample data class that will denote an individual view on the ViewPager. Here, I’ve taken an example class named Sample which has attributes as number, referencing the view’s number in a TextView and the color attribute, referencing the background color of an individual view on the ViewPager.

data class Sample (
var number: Int,
var color: String
)

ViewPager item layout file

Now, create a Layout file for an individual item view on the ViewPager. Here, we have just a TextView on it to show the number of the ViewPager which is wrapped on a CardView with a dynamic background color. The file is named custom_infinite_pager_layout.xml

Adapter class

Then create a RecyclerView Adapter for organizing view items on the ViewPager2. The file InfiniteRecyclerAdapter.kt is mentioned below.

In the above file, our first part of the solution towards infinite ViewPager works. See what the lines mentioned below does on the above adapter class.

private val newList: List<Sample> =
listOf(originalList.last()) + originalList + listOf(originalList.first())

These lines make a new list of Sample class items out of the original list passed into the adapter class. It appends the last item of the original list at the very beginning and then adds the original list, followed by the first item of the original list.

Sample Activity

And finally, the activity file SampleActivity.kt sets up everything.

Here, the first important thing is to make the infiniteViewPager’s current item to position 1, as position 0 is taken by the fake last item. As shown below.

infiniteViewPager.currentItem = 1

The second and the most important thing is adding an infiniteViewPager’s registerOnPageChangeCallback for performing our second workaround required for infinite scrolling.

private fun onInfinitePageChangeCallback(listSize: Int) {
infiniteViewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageScrollStateChanged(state: Int) {
super.onPageScrollStateChanged(state)

if (state == ViewPager2.SCROLL_STATE_IDLE) {
when (infiniteViewPager.currentItem) {
listSize - 1 -> infiniteViewPager.setCurrentItem(1, false)
0 -> infiniteViewPager.setCurrentItem(listSize - 2, false)
}
}
}

override fun onPageSelected(position: Int) {
super.onPageSelected(position)

if (position != 0 && position != listSize - 1) {
// pageIndicatorView.setSelected(position-1)
}
}
})
}

onPageScrollStateChanged() get notified when ever scroll state changes from ViewPager2.SCROLL_STATE_DRAGGING to ViewPager2.SCROLL_STATE_SETTLING to ViewPager2.SCROLL_STATE_IDLE. When the state after dragging, settles, and became idle, if the current item of the ViewPager is listsize-1 (fake last item), set the new current item to 1 (actual first item). And similarly, if the current item of the ViewPager is 0 (fake first item), set the new current item to listsize-2 (actual last item).

Also if you have used a pageIndicatorView for indicating the pages on which the ViewPager is currently on, update it in onPageSelected() method as shown above.

Final Output | Inifinite ViewPager2

Finally, we have our desired bi-direction infinite scrolling ViewPager2 ready!

For reference, I have added the whole project to a Github repository.

There I have shown a comparison between a Normal ViewPager2 and an Infinite ViewPager2 in code. Clone the project onto your system, open it in Android Studio, run the app on a physical device or an emulator to visualize the concept.

If you are keen and enthusiastic to know more about Android Development, please do follow!

--

--

Ashish Pandey

An enthusiastic Android Developer sharing stuff that pops up inside my right brain out of processed stuff from my left brain