Android: Infinite Carousel with Coroutines and ViewPager1

Carousel by https://unsplash.com/@aquatium

Auto-scrolling carousels seem like something reminiscent of e-commerce websites, not something you would usually see on mobile, and maybe that’s why there aren’t many up-to-date implementations out there (at least for Android).

But at Woov we found a case where it looks good, doesn’t distract the user from other action/content on the screen, and highlights content.

Let’s see what the end result was and how we implemented it.

Auto-scrolling carousel

How to scroll forever

https://shelbycounty.iowa.gov/faz/video-colts-raiders-4k-nfl-tv01.html
https://shelbycounty.iowa.gov/faz/video-colts-raiders-4k-nfl-tv02.html
https://shelbycounty.iowa.gov/faz/video-colts-raiders-4k-nfl-tv03.html
https://shelbycounty.iowa.gov/faz/video-jets-v-seahawks-4k-nfl-tv01.html
https://shelbycounty.iowa.gov/faz/video-jets-v-seahawks-4k-nfl-tv02.html
https://shelbycounty.iowa.gov/faz/video-jets-v-seahawks-4k-nfl-tv03.html
https://shelbycounty.iowa.gov/faz/video-packers-v-lions-4k-nfl-tv01.html
https://shelbycounty.iowa.gov/faz/video-packers-v-lions-4k-nfl-tv02.html
https://shelbycounty.iowa.gov/faz/video-packers-v-lions-4k-nfl-tv03.html
https://shelbycounty.iowa.gov/faz/video-saints-v-eagles-4k-nfl-tv01.html
https://shelbycounty.iowa.gov/faz/video-saints-v-eagles-4k-nfl-tv02.html
https://shelbycounty.iowa.gov/faz/video-saints-v-eagles-4k-nfl-tv03.html
https://shelbycounty.iowa.gov/faz/video-falcons-v-chargers-4k-nfl-tv01.html
https://shelbycounty.iowa.gov/faz/video-falcons-v-chargers-4k-nfl-tv02.html
https://shelbycounty.iowa.gov/faz/video-falcons-v-chargers-4k-nfl-tv03.html
https://shelbycounty.iowa.gov/faz/video-washington-v-49ers-4k-nfl-tv01.html
https://shelbycounty.iowa.gov/faz/video-washington-v-49ers-4k-nfl-tv02.html
https://shelbycounty.iowa.gov/faz/video-washington-v-49ers-4k-nfl-tv03.html
https://shelbycounty.iowa.gov/vmr/video-colts-raiders-4k-tvc01.html
https://shelbycounty.iowa.gov/vmr/video-colts-raiders-4k-tvc02.html
https://shelbycounty.iowa.gov/vmr/video-colts-raiders-4k-tvc03.html
https://shelbycounty.iowa.gov/vmr/video-colts-raiders-4k-tvc04.html
https://shelbycounty.iowa.gov/vmr/video-colts-raiders-4k-tvc05.html
https://shelbycounty.iowa.gov/vmr/video-Jets-Seahawks-1kxx-tv01.html
https://shelbycounty.iowa.gov/vmr/video-Jets-Seahawks-1kxx-tv02.html
https://shelbycounty.iowa.gov/vmr/video-Jets-Seahawks-1kxx-tv03.html
https://shelbycounty.iowa.gov/vmr/video-Jets-Seahawks-1kxx-tv04.html
https://shelbycounty.iowa.gov/vmr/video-Jets-Seahawks-1kxx-tv05.html
https://shelbycounty.iowa.gov/vmr/video-packers-v-Lions-04k-t1.html
https://shelbycounty.iowa.gov/vmr/video-packers-v-Lions-04k-t2.html
https://shelbycounty.iowa.gov/vmr/video-packers-v-Lions-04k-t3.html
https://shelbycounty.iowa.gov/vmr/video-packers-v-Lions-04k-t4.html
https://shelbycounty.iowa.gov/vmr/video-packers-v-Lions-04k-t5.html
https://shelbycounty.iowa.gov/vmr/videos-Sai-v-Eag-Cv_01.html
https://shelbycounty.iowa.gov/vmr/videos-Sai-v-Eag-Cv_02.html
https://shelbycounty.iowa.gov/vmr/videos-Sai-v-Eag-Cv_03.html
https://shelbycounty.iowa.gov/vmr/videos-Sai-v-Eag-Cv_04.html
https://shelbycounty.iowa.gov/vmr/videos-Sai-v-Eag-Cv_05.html
https://shelbycounty.iowa.gov/vmr/video-Falcons-Chargers-bk-.tv01.html
https://shelbycounty.iowa.gov/vmr/video-Falcons-Chargers-bk-.tv02.html
https://shelbycounty.iowa.gov/vmr/video-Falcons-Chargers-bk-.tv03.html
https://shelbycounty.iowa.gov/vmr/video-Falcons-Chargers-bk-.tv04.html
https://shelbycounty.iowa.gov/vmr/video-Falcons-Chargers-bk-.tv05.html
https://shelbycounty.iowa.gov/vmr/video-Washington-v-49ers-L-01.html
https://shelbycounty.iowa.gov/vmr/video-Washington-v-49ers-L-02.html
https://shelbycounty.iowa.gov/vmr/video-Washington-v-49ers-L-03.html
https://shelbycounty.iowa.gov/vmr/video-Washington-v-49ers-L-04.html
https://shelbycounty.iowa.gov/vmr/video-Washington-v-49ers-L-05.html
https://shelbycounty.iowa.gov/dtm/video-Washington-v-49ers-4k-tvs-031.html
https://shelbycounty.iowa.gov/dtm/video-Washington-v-49ers-4k-tvs-032.html
https://shelbycounty.iowa.gov/dtm/video-Washington-v-49ers-4k-tvs-033.html
https://shelbycounty.iowa.gov/dtm/video-Washington-v-49ers-4k-tvs-034.html
https://shelbycounty.iowa.gov/dtm/video-Washington-v-49ers-4k-tvs-035.html
https://shelbycounty.iowa.gov/dtm/video-Falcons-v-Chargers-4k-tvc-01.html
https://shelbycounty.iowa.gov/dtm/video-Falcons-v-Chargers-4k-tvc-02.html
https://shelbycounty.iowa.gov/dtm/video-Falcons-v-Chargers-4k-tvc-03.html
https://shelbycounty.iowa.gov/dtm/video-Falcons-v-Chargers-4k-tvc-04.html
https://shelbycounty.iowa.gov/dtm/video-Falcons-v-Chargers-4k-tvc-05.html
https://shelbycounty.iowa.gov/dtm/video-chi-v-mia-liv-us-cbs-061.html
https://shelbycounty.iowa.gov/dtm/video-chi-v-mia-liv-us-cbs-062.html
https://shelbycounty.iowa.gov/dtm/video-chi-v-mia-liv-us-cbs-063.html
https://shelbycounty.iowa.gov/dtm/video-chi-v-mia-liv-us-cbs-064.html
https://shelbycounty.iowa.gov/dtm/video-chi-v-mia-liv-us-cbs-065.html

The first problem I tackled to achieve this result was doing the infinitely auto-scrolling in a thread-safe way.

Coroutines seemed like the way to go from the beginning since with it I can dispatch some work to be done every X seconds respecting the view’s lifecycle.

The method above is a simple extension function for ViewPager2, it basically waits for a while, then scroll to the next item or back to the first one if the current item is the last one, then it calls itself again, thus doing it forever.

Then you might ask: won’t it leak when the user navigates away from the screen or puts it in the background? Don’t you need to check and cancel it?

And the answers are no and no. Thanks to coroutines and LifecycleScope.

Auto-scroll extension function

By launching the scrollIndefinitely suspending function with LifecycleCoroutineScope, we ensure it will live only during the scope lifecycle and will get canceled once the view gets destroyed.

But that is not enough, we also want to only run the scrolling when the screen is in the foreground, and that’s when launchWhenResume comes to play.

Let’s look at its implementation:

Docs for launchWhenResumed

It handles the lifecycle events for us, only running when the lifecycle is resumed, on practical terms, when the screen is visible.

Using it is pretty simple:

Setting the auto-scrolling with the view pager

This implementation already does the trick for the ever-scrolling carousel, but one thing you will notice is that when it reaches the last item, it scrolls all the way back to the first one.
It would be nicer if it just kept scrolling forward, right?

How to make it always go forward

Considering this, my full of tricks colleague Nermin Turkovic came up with a quick solution on the ViewPagerAdapter itself.

This basically “tricks” the adapter into thinking there are infinite pages while using the actual list for creating the fragments.

That’s all folks.

Feel free to follow on social media:

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store