New Compose Multiplatform components arrived on Composables UICheck it out →


Horizontal page indicator for use with [HorizontalPager], representing the currently active page and the total number of pages. Pages are indicated as a Circle shape. The indicator shows up to six pages individually - if there are more than six pages, [HorizontalPageIndicator] shows a half-size indicator to the left or right to indicate that more are available.

Here's how different positions 0..10 might be visually represented: "X" is selected item, "O" and "o" full and half size items respectively.

O X O O O o - 2nd position out of 10. There are no more items on the left but more on the right o O O O X o - current page could be 6, 7 or 8 out of 10, as there are more possible items on the left and on the right o O O O X O - current page is 9 out of 10, as there're no more items on the right

[HorizontalPageIndicator] is linear or curved, depending on the screen shape of the device - for circular screens it will be curved, whilst for square screens it will be linear.

Last updated:


dependencies {


fun HorizontalPageIndicator(
    pageIndicatorState: PageIndicatorState,
    modifier: Modifier = Modifier,
    selectedColor: Color = MaterialTheme.colorScheme.onBackground,
    unselectedColor: Color = selectedColor.copy(alpha = 0.3f),
    indicatorSize: Dp = 6.dp,
    spacing: Dp = 4.dp


pageIndicatorStateThe state object of a [HorizontalPageIndicator] to be used to observe the Pager's state.
modifierModifier to be applied to the [HorizontalPageIndicator]
selectedColorThe color of the selected [HorizontalPageIndicator] item
unselectedColorThe color of unselected [HorizontalPageIndicator] items. Defaults to [selectedColor] with 30% alpha
indicatorSizeThe size of each [HorizontalPageIndicator] item in [Dp]
spacingThe spacing between indicator items in [Dp] *

Code Example


fun HorizontalPageIndicatorSample() {
    val pageCount = 9
    var selectedPage by remember { mutableStateOf(0) }
    var finalValue by remember { mutableStateOf(0) }

    val animatedSelectedPage by animateFloatAsState(
        targetValue = selectedPage.toFloat(), label = "animateSelectedPage",
    ) {
        finalValue = it.toInt()

    val pageIndicatorState: PageIndicatorState =
        rememberPageIndicatorState(pageCount) { animatedSelectedPage }

        modifier = Modifier
    ) {
            modifier = Modifier.align(Alignment.Center),
            value = selectedPage,
            increaseIcon = { Icon(InlineSliderDefaults.Increase, "Increase") },
            decreaseIcon = { Icon(InlineSliderDefaults.Decrease, "Decrease") },
            valueProgression = 0 until pageCount,
            onValueChange = { selectedPage = it }
            pageIndicatorState = pageIndicatorState