Blog Infos
Author
Published
Topics
,
Author
Published

This story will show how to create ViewPager (HorizontalPager /VerticalPager ) in Jetpack Compose.

Photo by Amélie Mourichon on Unsplash

 

Content
  • Dependency
  • Horizontal Pager (Simple Example)
  • Horizontal Pager with Next and Prev Button (Manual Scrolling)
  • Horizontal Pager with Images and Dot Indicators
  • Vertical Pager with Images
  • Github Project
Dependency
implementation 'androidx.compose.foundation:foundation:1.4.1'
composeOptions {
        kotlinCompilerExtensionVersion '1.4.4'
    }
Horizontal Pager Composable
fun HorizontalPager(
pageCount: Int,
modifier: Modifier = Modifier,
state: PagerState = rememberPagerState(),
contentPadding: PaddingValues = PaddingValues(0.dp),
pageSize: PageSize = PageSize.Fill,
beyondBoundsPageCount: Int = 0,
pageSpacing: Dp = 0.dp,
verticalAlignment: Alignment.Vertical = Alignment.CenterVertically,
flingBehavior: SnapFlingBehavior = PagerDefaults.flingBehavior(state = state),
userScrollEnabled: Boolean = true,
reverseLayout: Boolean = false,
key: ((index: Int) -> Any)? = null,
pageNestedScrollConnection: NestedScrollConnection = PagerDefaults.pageNestedScrollConnection(
Orientation.Horizontal
),
pageContent: @Composable (page: Int) -> Unit
)
  • pageCount — thats number of pages we want to show
  • pageSize — it represents size of the pager itself (not the content size), default value is PagerSize.Fill that means for HorizontalPager it will take complete width of the screen and for VerticalPager it will take complete height of the screen as default size of the pager.
  • pageSpacing — it represents the distance between two pagers of HorizontalPager or VerticalPager
  • state — it keeps the pager state i.e which page user is currently visible and provides the scrolling functionality
  • pageContent —it provides composable lambda which will represent actual content of the pager. lambda provides the page index of the page which is currently being displayed on screen which will be used to disable the custom page inside HorizontalPager
  • modifier — that’s generic modifier parameter as every composable function has.
Horizontal Pager (Simple Example)
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun HorizontalPagerSimpleExample() {
val pagerState = rememberPagerState()
HorizontalPager(pageCount = 5, state = pagerState) {
Box(modifier = Modifier
.fillMaxWidth()
.height(300.dp)
.background(Color.Gray),
contentAlignment = Alignment.Center
) {
Text(text = "Page Index : $it")
}
}
}

Job Offers

Job Offers


    Senior Android Developer

    SumUp
    Berlin
    • Full Time
    apply now

    Senior Android Engineer

    Carly Solutions GmbH
    Munich
    • Full Time
    apply now

OUR VIDEO RECOMMENDATION

, ,

Jetpack Compose Navigation: Beyond The Basics

One of the challenges facing Android engineers today is that while there is a myriad of information available surrounding the more established navigation with fragments, there are few practical resources on how to adapt to…
Watch Video

Jetpack Compose Navigation: Beyond The Basics

Miguel Kano
Android Engineer
Robinhood Markets, Inc

Jetpack Compose Navigation: Beyond The Basics

Miguel Kano
Android Engineer
Robinhood Markets, I ...

Jetpack Compose Navigation: Beyond The Basics

Miguel Kano
Android Engineer
Robinhood Markets, Inc

Jobs

Output:

Horizontal Pager with Next and Prev Button (Manual Scrolling)
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun HorizontalPagerWithNextPrevButtonExample() {
val pagerState = rememberPagerState()
val coroutineScope = rememberCoroutineScope()
Box (
modifier = Modifier
.fillMaxWidth()
.height(300.dp)
) {
HorizontalPager(pageCount = 5, state = pagerState) { pageIndex ->
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.Gray),
contentAlignment = Alignment.Center
) {
Text(text = "Current Page Index $pageIndex")
}
}
Row(modifier = Modifier
.align(Alignment.BottomCenter)
.padding(bottom = 16.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
val prevButtonVisible = remember {
derivedStateOf {
pagerState.currentPage > 0
}
}
val nextButtonVisible = remember {
derivedStateOf {
pagerState.currentPage < 4 // total pages are 5
}
}
Button(
enabled = prevButtonVisible.value,
onClick = {
val prevPageIndex = pagerState.currentPage - 1
coroutineScope.launch { pagerState.animateScrollToPage(prevPageIndex) }
},
) {
Text(text = "Prev")
}
Button(
enabled = nextButtonVisible.value ,
onClick = {
val nextPageIndex = pagerState.currentPage + 1
coroutineScope.launch { pagerState.animateScrollToPage(nextPageIndex) }
},
) {
Text(text = "Next")
}
}
}
}
val prevButtonVisible = remember {
    derivedStateOf {
        pagerState.currentPage > 0
    }
}

Horizontal Pager with Images and Dot Indicators
implementation "com.google.accompanist:accompanist-pager-indicators:0.30.1"

Lets look at the final code below

@Composable
fun HorizontalPagerWithIndicatorsScreen() {
val images = listOf(
R.drawable.logo_android,
R.drawable.logo_kotlin,
R.drawable.logo_apple,
R.drawable.logo_fb,
R.drawable.logo_google,
)
Column {
HorizontalPagerWithIndicators(images)
}
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun HorizontalPagerWithIndicators(images: List<Int>) {
val pagerState = rememberPagerState()
Box(modifier = Modifier
.fillMaxWidth()
.height(300.dp)
) {
HorizontalPager(pageCount = 5, state = pagerState) {
Image(
painter = painterResource(id = images[it]),
contentScale = ContentScale.Crop,
contentDescription = "" )
}
HorizontalPagerIndicator(
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(bottom = 10.dp),
pageCount = 5,
pagerState = pagerState,
)
}
}

Vertical Pager with Images
@Composable
fun VerticalPagerWithImagesAndIndicatorsScreen() {
val images = listOf(
R.drawable.logo_android,
R.drawable.logo_kotlin,
R.drawable.logo_gradle,
R.drawable.logo_github,
R.drawable.logo_google,
)
Column {
VerticalPagerWithImagesAndIndicators(images)
}
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun VerticalPagerWithImagesAndIndicators(images: List<Int>) {
val pagerState = rememberPagerState()
VerticalPager(
pageCount = 5,
pageSize = PageSize.Fixed(300.dp),
pageSpacing = 8.dp,
state = pagerState) {
Image(
painter = painterResource(id = images[it]),
contentScale = ContentScale.Crop,
contentDescription = "" )
}
}
  • pageSize — it represents the size of page to be use, we are using Fixed 300.dp in our code that means on screen we will see multiple pages depending upon how many can appear on any device size
  • pageSpacing — it handles the spacing between two pages

Migration from Accompanist to Compose Foundation API
Sources
Photo Credits/Attributes
Github Project

 

👉 Follow for more stories on Android Development and 👏 if you liked it

 

This article was previously published on proandroiddev.com

YOU MAY BE INTERESTED IN

YOU MAY BE INTERESTED IN

blog
It’s one of the common UX across apps to provide swipe to dismiss so…
READ MORE
blog
In this part of our series on introducing Jetpack Compose into an existing project,…
READ MORE
blog
In the world of Jetpack Compose, where designing reusable and customizable UI components is…
READ MORE
blog

How to animate BottomSheet content using Jetpack Compose

Early this year I started a new pet project for listening to random radio…
READ MORE

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.

Menu