Better Programming

Advice for programmers.

Follow publication

Implement Horizontal and Vertical ViewPager in Jetpack Compose

Implementing ViewPager in Jetpack Compose

Igor Stevanovic
Better Programming
Published in
4 min readJul 14, 2022

--

The Jetpack Compose logo used in this image is the official logo created by Google

In Jetpack Compose we don’t have anything by default like ViewPager that we could use, but we have a solution for that. We are going to use Accompanist Pager library. First, we are gonna add the dependency to the app-level build.gradle file:

implementation "com.google.accompanist:accompanist-pager:0.23.1"

Note: At the time of writing this article, 0.23.1 was the newest stable version. Check if there is a newer version.

“A library which provides paging layouts for Jetpack Compose. If you’ve used Android’s ViewPager before, it has similar properties.” According to Pager official documentation

HorizontalPager

HorizontalPager is composable where content is ordered horizontally and displayed as pages. We are going to create a data class called HorizontalPagerContent which will represent horizontal pager content.

data class HorizontalPagerContent(
val title: String,
val subtitle: String,
val description: String
)

Next is to create a list of items that will be shown in this pager:

fun createItems() = listOf(
HorizontalPagerContent(title = "Title1", subtitle = "Subtitle1", description = "Description1"),
HorizontalPagerContent(title = "Title2", subtitle = "Subtitle2", description = "Description2"),
HorizontalPagerContent(title = "Title3", subtitle = "Subtitle3", description = "Description3"),
HorizontalPagerContent(title = "Title4", subtitle = "Subtitle4", description = "Description4"),
HorizontalPagerContent(title = "Title5", subtitle = "Subtitle5", description = "Description5")
)

It is a simple function that returns a list of HorizontalPagerContent items. HorizontalPager has two mandatory parameters and they arecount: Int and content: @Composable PagerScope.(page: Int) -> Unit, every other param is optional and there are many like: modifier, reverseLayout, verticalAlignment, and so on. One optional parameter that I didn’t mention and that can be very useful is state: PagerState which represents the state of the pager. That state you can use to get the current page, page count, and to scroll to the specific page which we will show in our example. So our main composable will look something like this:

Note: we need to add ExperimentalPermissionsApi annotation because all of the APIs in the library are still experimental.

First, we create items and pagerState and pass both of them to the HorizontalPager. The content composable returns index of the current page which we can use to get that item from the list and load its data. At the end of our main composable, we can see a button that will, when pressed, scroll to the third page. To scroll you can use animateScrollToPage or scrollToPage depends on what you need, but both of them need to be called inside Coroutine. The difference between them is that animateScrollToPage scrolls smoothly.

The next thing that we are gonna add is indicators and tabs. For that we need to add a new accompanist library:

implementation "com.google.accompanist:accompanist-pager-indicators:0.23.1"

Note: At the time of writing this article, 0.23.1 was the newest stable version. Check if there is a newer version.

Adding indicators is very simple, we just need to add HorizontalPagerIndicator and pass pagerState. So it looks like this for example:

HorizontalPagerIndicator(
pagerState = pagerState,
modifier = Modifier
.align(Alignment.CenterHorizontally)
.padding(16.dp),
)

Not bad, right? Now let’s add tabs, we are going to create a new composable called HorizontalTabs, and in that composable, we will use TabRow and Tab from Accompanist Pager Indicator library. This composable will look like this:

TabRow has two mandatory parameters selectedTabIndex: Int and tabs: @Composable () -> Unit. Parameter indicator is used here to animate indicator drawing inside tabs space, without that indicator would only jump from one tab to another. Inside tabs composable we just pass what will our tabs look like. We are using composable Tab from this library, which has mandatory parameters: selected: Boolean, onClick: () -> Unit, and content: @Composable ColumnScope.() -> Unit. When clicked on any of the tabs we are smoothly scrolling to it.

That was HorizontalPager and main features that are used around it. Now we are going to implement VerticalPager.

VerticalPager

VerticalPager is composable where content is ordered vertically and displayed as pages.

Implementing VerticalPager is basically the same thing as implementing HorizontalPager.

You just need to use VerticalPager instead of HorizontalPager and for indicators you use VerticalPagerIndicator instead of HorizontalPagerIndicator. Everything else is the same. So it would look like this:

That would be all for this article, I hope you liked it!
All of the source code you can find in my GitHub repo.

Connect with me on:
Github
LinkedIn
Twitter
Portfolio website

If you want to learn about requesting permissions in Jetpack Compose, take a look at this article:

Resources

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Igor Stevanovic
Igor Stevanovic

Written by Igor Stevanovic

Android Engineer, Freelancer and Writer