To flip through content horizontally or vertically, you can use the[`HorizontalPager`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/pager/package-summary#HorizontalPager(kotlin.Int,androidx.compose.ui.Modifier,androidx.compose.foundation.pager.PagerState,androidx.compose.foundation.layout.PaddingValues,androidx.compose.foundation.pager.PageSize,kotlin.Int,androidx.compose.ui.unit.Dp,androidx.compose.ui.Alignment.Vertical,androidx.compose.foundation.gestures.snapping.SnapFlingBehavior,kotlin.Boolean,kotlin.Boolean,kotlin.Function1,androidx.compose.ui.input.nestedscroll.NestedScrollConnection,kotlin.Function1))and[`VerticalPager`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/pager/package-summary#VerticalPager(kotlin.Int,androidx.compose.ui.Modifier,androidx.compose.foundation.pager.PagerState,androidx.compose.foundation.layout.PaddingValues,androidx.compose.foundation.pager.PageSize,kotlin.Int,androidx.compose.ui.unit.Dp,androidx.compose.ui.Alignment.Horizontal,androidx.compose.foundation.gestures.snapping.SnapFlingBehavior,kotlin.Boolean,kotlin.Boolean,kotlin.Function1,androidx.compose.ui.input.nestedscroll.NestedScrollConnection,kotlin.Function1))composables. These have similar functions to[`ViewPager`](https://developer.android.com/reference/kotlin/androidx/viewpager/widget/ViewPager)in the view system. By default,`HorizontalPager`takes up the full screen width and`VerticalPager`takes up the full height. The pagers also only fling one page at a time. All of these defaults are configurable.

## HorizontalPager

To create a pager that scrolls horizontally left and right, use`HorizontalPager`:
**Figure 1** . Demo of`HorizontalPager`

<br />

```kotlin
// Display 10 items
val pagerState = rememberPagerState(pageCount = {
    10
})
HorizontalPager(state = pagerState) { page ->
    // Our page content
    Text(
        text = "Page: $page",
        modifier = Modifier.fillMaxWidth()
    )
}https://github.com/android/snippets/blob/95aeebd507b29719a9e7d5a839f101bbbe42ea72/compose/snippets/src/main/java/com/example/compose/snippets/layouts/PagerSnippets.kt#L111-L121
```

<br />

## VerticalPager

To create a pager that scrolls up and down, use`VerticalPager`:
**Figure 2** . Demo of`VerticalPager`

<br />

<br />

```kotlin
// Display 10 items
val pagerState = rememberPagerState(pageCount = {
    10
})
VerticalPager(state = pagerState) { page ->
    // Our page content
    Text(
        text = "Page: $page",
        modifier = Modifier.fillMaxWidth()
    )
}https://github.com/android/snippets/blob/95aeebd507b29719a9e7d5a839f101bbbe42ea72/compose/snippets/src/main/java/com/example/compose/snippets/layouts/PagerSnippets.kt#L129-L139
```

<br />

## Lazy creation

Pages in both`HorizontalPager`and`VerticalPager`are[lazily composed](https://developer.android.com/develop/ui/compose/lists#lazy)and laid-out when required. As the user scrolls through pages, the composable removes any pages which are no longer required.

### Load more pages offscreen

By default, the pager only loads the visible pages on-screen. To load more pages offscreen, set`beyondBoundsPageCount`to a value higher than zero.

## Scroll to an item in the pager

To scroll to a certain page in the pager, create a[`PagerState`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/pager/PagerState)object using[`rememberPagerState()`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/pager/package-summary#rememberPagerState(kotlin.Int,kotlin.Float))and pass it as the`state`parameter to the pager. You can call[`PagerState#scrollToPage()`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/pager/PagerState#scrollToPage(kotlin.Int,kotlin.Float))on this state, inside a`CoroutineScope`:

<br />

```kotlin
val pagerState = rememberPagerState(pageCount = {
    10
})
HorizontalPager(state = pagerState) { page ->
    // Our page content
    Text(
        text = "Page: $page",
        modifier = Modifier
            .fillMaxWidth()
            .height(100.dp)
    )
}

// scroll to page
val coroutineScope = rememberCoroutineScope()
Button(onClick = {
    coroutineScope.launch {
        // Call scroll to on pagerState
        pagerState.scrollToPage(5)
    }
}, modifier = Modifier.align(Alignment.BottomCenter)) {
    Text("Jump to Page 5")
}https://github.com/android/snippets/blob/95aeebd507b29719a9e7d5a839f101bbbe42ea72/compose/snippets/src/main/java/com/example/compose/snippets/layouts/PagerSnippets.kt#L148-L170
```

<br />

If you want to animate to the page, use the[`PagerState#animateScrollToPage()`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/pager/PagerState#animateScrollToPage(kotlin.Int,kotlin.Float,androidx.compose.animation.core.AnimationSpec))function:

<br />

```kotlin
val pagerState = rememberPagerState(pageCount = {
    10
})

HorizontalPager(state = pagerState) { page ->
    // Our page content
    Text(
        text = "Page: $page",
        modifier = Modifier
            .fillMaxWidth()
            .height(100.dp)
    )
}

// scroll to page
val coroutineScope = rememberCoroutineScope()
Button(onClick = {
    coroutineScope.launch {
        // Call scroll to on pagerState
        pagerState.animateScrollToPage(5)
    }
}, modifier = Modifier.align(Alignment.BottomCenter)) {
    Text("Jump to Page 5")
}https://github.com/android/snippets/blob/95aeebd507b29719a9e7d5a839f101bbbe42ea72/compose/snippets/src/main/java/com/example/compose/snippets/layouts/PagerSnippets.kt#L180-L203
```

<br />

## Get notified about page state changes

[`PagerState`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/pager/PagerState)has three properties with information about pages:[`currentPage`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/pager/PagerState#currentPage()),[`settledPage`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/pager/PagerState#settledPage()), and[`targetPage`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/pager/PagerState#targetPage()).

- `currentPage`: The closest page to the snap position. By default, the snap position is at the start of the layout.
- `settledPage`: The page number when no animation or scrolling is running. This is different from the`currentPage`property in that the`currentPage`immediately updates if the page is close enough to the snap position, but`settledPage`remains the same until all the animations are finished running.
- `targetPage`: The proposed stop position for a scrolling movement.

You can use the`snapshotFlow`function to observe changes to these variables and react to them. For example, to send an analytics event on each page change, you can do the following:

<br />

```kotlin
val pagerState = rememberPagerState(pageCount = {
    10
})

LaunchedEffect(pagerState) {
    // Collect from the a snapshotFlow reading the currentPage
    snapshotFlow { pagerState.currentPage }.collect { page ->
        // Do something with each page change, for example:
        // viewModel.sendPageSelectedEvent(page)
        Log.d("Page change", "Page changed to $page")
    }
}

VerticalPager(
    state = pagerState,
) { page ->
    Text(text = "Page: $page")
}https://github.com/android/snippets/blob/95aeebd507b29719a9e7d5a839f101bbbe42ea72/compose/snippets/src/main/java/com/example/compose/snippets/layouts/PagerSnippets.kt#L212-L229
```

<br />

## Add a page indicator

To add an indicator to a page, use the`PagerState`object to get information about which page is selected out of the number of pages, and draw your custom indicator.

For example, to create a circle indicator, you can repeat the number of circles and change the circle color based on if the page is selected, using`pagerState.currentPage`:

<br />

```kotlin
val pagerState = rememberPagerState(pageCount = {
    4
})
HorizontalPager(
    state = pagerState,
    modifier = Modifier.fillMaxSize()
) { page ->
    // Our page content
    Text(
        text = "Page: $page",
    )
}
Row(
    Modifier
        .wrapContentHeight()
        .fillMaxWidth()
        .align(Alignment.BottomCenter)
        .padding(bottom = 8.dp),
    horizontalArrangement = Arrangement.Center
) {
    repeat(pagerState.pageCount) { iteration ->
        val color = if (pagerState.currentPage == iteration) Color.DarkGray else Color.LightGray
        Box(
            modifier = Modifier
                .padding(2.dp)
                .clip(CircleShape)
                .background(color)
                .size(16.dp)
        )
    }
}https://github.com/android/snippets/blob/95aeebd507b29719a9e7d5a839f101bbbe42ea72/compose/snippets/src/main/java/com/example/compose/snippets/layouts/PagerSnippets.kt#L381-L411
```

<br />

![Pager showing a circle indicator below the content](https://developer.android.com/static/develop/ui/compose/images/layouts/pager/indicator.png)**Figure 3**. Pager showing a circle indicator below the content

## Apply item scroll effects to content

A common use case is to use the scroll position to apply effects to your pager items. To find out how far a page is from the selected page, you can use[`PagerState.currentPageOffsetFraction`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/pager/PagerState#currentPageOffsetFraction()). You can then apply transformation effects to your content based on the distance from the selected page.
**Figure 4**. Applying transformations to Pager content

For example, to adjust the opacity of items based on how far they are from the center, change the`alpha`using[`Modifier.graphicsLayer`](https://developer.android.com/develop/ui/compose/graphics/draw/modifiers#graphicsLayer)on an item inside the pager:

<br />

```kotlin
val pagerState = rememberPagerState(pageCount = {
    4
})
HorizontalPager(state = pagerState) { page ->
    Card(
        Modifier
            .size(200.dp)
            .graphicsLayer {
                // Calculate the absolute offset for the current page from the
                // scroll position. We use the absolute value which allows us to mirror
                // any effects for both directions
                val pageOffset = (
                    (pagerState.currentPage - page) + pagerState
                        .currentPageOffsetFraction
                    ).absoluteValue

                // We animate the alpha, between 50% and 100%
                alpha = lerp(
                    start = 0.5f,
                    stop = 1f,
                    fraction = 1f - pageOffset.coerceIn(0f, 1f)
                )
            }
    ) {
        // Card content
    }
}https://github.com/android/snippets/blob/95aeebd507b29719a9e7d5a839f101bbbe42ea72/compose/snippets/src/main/java/com/example/compose/snippets/layouts/PagerSnippets.kt#L268-L294
```

<br />

## Custom page sizes

By default,`HorizontalPager`and`VerticalPager`takes up the full width or full height, respectively. You can set the`pageSize`variable to either have a[`Fixed`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/pager/PageSize.Fixed),[`Fill`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/pager/PageSize.Fill)(default), or a custom size calculation.

For example, to set a fixed width page of`100.dp`:

<br />

```kotlin
val pagerState = rememberPagerState(pageCount = {
    4
})
HorizontalPager(
    state = pagerState,
    pageSize = PageSize.Fixed(100.dp)
) { page ->
    // page content
}https://github.com/android/snippets/blob/95aeebd507b29719a9e7d5a839f101bbbe42ea72/compose/snippets/src/main/java/com/example/compose/snippets/layouts/PagerSnippets.kt#L350-L358
```

<br />

To size the pages based on the viewport size, use a custom page size calculation. Create a custom[`PageSize`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/pager/PageSize)object and divide the`availableSpace`by three, taking into account the spacing between the items:

<br />

```kotlin
private val threePagesPerViewport = object : PageSize {
    override fun Density.calculateMainAxisPageSize(
        availableSpace: Int,
        pageSpacing: Int
    ): Int {
        return (availableSpace - 2 * pageSpacing) / 3
    }
}https://github.com/android/snippets/blob/95aeebd507b29719a9e7d5a839f101bbbe42ea72/compose/snippets/src/main/java/com/example/compose/snippets/layouts/PagerSnippets.kt#L509-L516
```

<br />

## Content padding

`HorizontalPager`and`VerticalPager`both support changing the content padding, which lets you influence the maximum size and alignment of pages.

For example, setting the`start`padding aligns the pages towards the end:
![Pager with start padding showing the content aligned towards the end](https://developer.android.com/static/develop/ui/compose/images/layouts/pager/contentpadding-start.png)**Figure 5**. Pager with start padding.

<br />

```kotlin
val pagerState = rememberPagerState(pageCount = {
    4
})
HorizontalPager(
    state = pagerState,
    contentPadding = PaddingValues(start = 64.dp),
) { page ->
    // page content
}https://github.com/android/snippets/blob/95aeebd507b29719a9e7d5a839f101bbbe42ea72/compose/snippets/src/main/java/com/example/compose/snippets/layouts/PagerSnippets.kt#L302-L310
```

<br />

Setting both the`start`and`end`padding to the same value centers the item horizontally:
![Pager with start and end padding showing the content centered](https://developer.android.com/static/develop/ui/compose/images/layouts/pager/contentpadding-horizontal.png)**Figure 6**. Pager with horizontal padding.

<br />

```kotlin
val pagerState = rememberPagerState(pageCount = {
    4
})
HorizontalPager(
    state = pagerState,
    contentPadding = PaddingValues(horizontal = 32.dp),
) { page ->
    // page content
}https://github.com/android/snippets/blob/95aeebd507b29719a9e7d5a839f101bbbe42ea72/compose/snippets/src/main/java/com/example/compose/snippets/layouts/PagerSnippets.kt#L318-L326
```

<br />

Setting the`end`padding aligns the pages towards the start:
![Pager with start and end padding showing the content aligned to the start](https://developer.android.com/static/develop/ui/compose/images/layouts/pager/contentpadding-end.png)**Figure 7**. Pager with end padding.

<br />

```kotlin
val pagerState = rememberPagerState(pageCount = {
    4
})
HorizontalPager(
    state = pagerState,
    contentPadding = PaddingValues(end = 64.dp),
) { page ->
    // page content
}https://github.com/android/snippets/blob/95aeebd507b29719a9e7d5a839f101bbbe42ea72/compose/snippets/src/main/java/com/example/compose/snippets/layouts/PagerSnippets.kt#L334-L342
```

<br />

You can set the`top`and`bottom`values to achieve similar effects for`VerticalPager`. The value`32.dp`is only used here as an example; you can set each of the padding dimensions to any value.

## Customize scroll behavior

The default`HorizontalPager`and`VerticalPager`composables specify how scrolling gestures work with the pager. However, you can customize and change the defaults such as the`pagerSnapDistance`or the`flingBehavior`.

### Snap distance

By default,`HorizontalPager`and`VerticalPager`set the maximum number of pages that a fling gesture can scroll past to one page at a time. To change this, set[`pagerSnapDistance`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/pager/PagerSnapDistance)on the`flingBehavior`:

<br />

```kotlin
val pagerState = rememberPagerState(pageCount = { 10 })

val fling = PagerDefaults.flingBehavior(
    state = pagerState,
    pagerSnapDistance = PagerSnapDistance.atMost(10)
)

Column(modifier = Modifier.fillMaxSize()) {
    HorizontalPager(
        state = pagerState,
        pageSize = PageSize.Fixed(200.dp),
        beyondViewportPageCount = 10,
        flingBehavior = fling
    ) {
        PagerSampleItem(page = it)
    }
}https://github.com/android/snippets/blob/95aeebd507b29719a9e7d5a839f101bbbe42ea72/compose/snippets/src/main/java/com/example/compose/snippets/layouts/PagerSnippets.kt#L523-L539
```

<br />

## Create an auto-advancing pager

This section describes how to create an auto-advancing pager with page indicators in Compose. The collection of items automatically scroll horizontally, but users can also manually swipe between items. If a user interacts with the pager, it stops the automatic progression.

### Basic example

Together, the following snippets create a basic auto-advancing pager implementation with a visual indicator, in which each page renders as a different color:

<br />

```kotlin
@Composable
fun AutoAdvancePager(pageItems: List<Color>, modifier: Modifier = Modifier) {
    Box(modifier = Modifier.fillMaxSize()) {
        val pagerState = rememberPagerState(pageCount = { pageItems.size })
        val pagerIsDragged by pagerState.interactionSource.collectIsDraggedAsState()

        val pageInteractionSource = remember { MutableInteractionSource() }
        val pageIsPressed by pageInteractionSource.collectIsPressedAsState()

        // Stop auto-advancing when pager is dragged or one of the pages is pressed
        val autoAdvance = !pagerIsDragged && !pageIsPressed

        if (autoAdvance) {
            LaunchedEffect(pagerState, pageInteractionSource) {
                while (true) {
                    delay(2000)
                    val nextPage = (pagerState.currentPage + 1) % pageItems.size
                    pagerState.animateScrollToPage(nextPage)
                }
            }
        }

        HorizontalPager(
            state = pagerState
        ) { page ->
            Text(
                text = "Page: $page",
                textAlign = TextAlign.Center,
                modifier = modifier
                    .fillMaxSize()
                    .background(pageItems[page])
                    .clickable(
                        interactionSource = pageInteractionSource,
                        indication = LocalIndication.current
                    ) {
                        // Handle page click
                    }
                    .wrapContentSize(align = Alignment.Center)
            )
        }

        PagerIndicator(pageItems.size, pagerState.currentPage)
    }
}https://github.com/android/snippets/blob/95aeebd507b29719a9e7d5a839f101bbbe42ea72/compose/snippets/src/main/java/com/example/compose/snippets/layouts/PagerSnippets.kt#L417-L460
```

<br />

#### Key points about the code

- The`AutoAdvancePager`function creates a horizontally paging view with automatic advancement. It takes a list of`Color`objects as input, which are used as background colors for each page.
- `pagerState`is created using[`rememberPagerState`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/pager/package-summary#rememberPagerState(kotlin.Int,kotlin.Float,kotlin.Function0)), which holds the state of the pager.
- `pagerIsDragged`and`pageIsPressed`track user interaction.
- The[`LaunchedEffect`](https://developer.android.com/reference/kotlin/androidx/compose/runtime/package-summary#LaunchedEffect(kotlin.Any,kotlin.coroutines.SuspendFunction1))auto-advances the pager every two seconds unless the user drags the pager or presses one of the pages.
- [`HorizontalPager`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/pager/package-summary#HorizontalPager(androidx.compose.foundation.pager.PagerState,androidx.compose.ui.Modifier,androidx.compose.foundation.layout.PaddingValues,androidx.compose.foundation.pager.PageSize,kotlin.Int,androidx.compose.ui.unit.Dp,androidx.compose.ui.Alignment.Vertical,androidx.compose.foundation.gestures.TargetedFlingBehavior,kotlin.Boolean,kotlin.Boolean,kotlin.Function1,androidx.compose.ui.input.nestedscroll.NestedScrollConnection,androidx.compose.foundation.gestures.snapping.SnapPosition,androidx.compose.foundation.OverscrollEffect,kotlin.Function2))displays a list of pages, each with a`Text`composable displaying the page number. The modifier fills the page, sets the background color from`pageItems`, and makes the page clickable.

<br />

```kotlin
@Composable
fun PagerIndicator(pageCount: Int, currentPageIndex: Int, modifier: Modifier = Modifier) {
    Box(modifier = Modifier.fillMaxSize()) {
        Row(
            modifier = Modifier
                .wrapContentHeight()
                .fillMaxWidth()
                .align(Alignment.BottomCenter)
                .padding(bottom = 8.dp),
            horizontalArrangement = Arrangement.Center
        ) {
            repeat(pageCount) { iteration ->
                val color = if (currentPageIndex == iteration) Color.DarkGray else Color.LightGray
                Box(
                    modifier = modifier
                        .padding(2.dp)
                        .clip(CircleShape)
                        .background(color)
                        .size(16.dp)
                )
            }
        }
    }
}https://github.com/android/snippets/blob/95aeebd507b29719a9e7d5a839f101bbbe42ea72/compose/snippets/src/main/java/com/example/compose/snippets/layouts/PagerSnippets.kt#L476-L499
```

<br />

#### Key points about the code

- A[`Box`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#Box(androidx.compose.ui.Modifier,androidx.compose.ui.Alignment,kotlin.Boolean,kotlin.Function1))composable acts as the root element and contains a[`Row`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#Row(androidx.compose.ui.Modifier,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.ui.Alignment.Vertical,kotlin.Function1))to arrange the page indicators horizontally.
- A custom page indicator is displayed as a row of circles, where each`Box`clipped to a`CircleShape`represents a page.
- The current page's circle is colored as a`DarkGray`, while the other circles are`LightGray`. The`currentPageIndex`parameter determines which circle renders in dark gray.

#### Result

This video displays the basic auto-advancing pager from the preceding snippets:

<br />

**Figure 8**. An auto-advancing pager with a two second delay between each page progression.

<br />

## Additional resources

- [Display a paging list](https://developer.android.com/develop/ui/compose/quick-guides/content/display-paging-list?hl=en)