How can I create a dots indicator like this for a HorizontalPager in Jetpack Compose?
I found a few libs and examples, but non of them were animated like this.
How can I create a dots indicator like this for a HorizontalPager in Jetpack Compose?
I found a few libs and examples, but non of them were animated like this.
On
This is what I use:
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.spring
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
/**
* Pager indicator
* Adapted from [Pager in Compose](https://developer.android.com/jetpack/compose/layouts/pager#add-page)
*/
@Composable
fun PageIndicator(
numberOfPages: Int,
selectedPage: Int = 0,
selectedColor: Color = Color.White,
defaultColor: Color = Color.Gray,
defaultRadius: Dp = 8.dp,
selectedLength: Dp = 25.dp,
space: Dp = 4.dp,
modifier: Modifier = Modifier
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(space),
modifier = modifier
) {
repeat(numberOfPages) {
Indicator(
isSelected = it == selectedPage,
selectedColor = selectedColor,
defaultColor = defaultColor,
defaultRadius = defaultRadius,
selectedLength = selectedLength,
)
}
}
}
/**
* pager indicator item
*/
@Composable
fun Indicator(
isSelected: Boolean,
selectedColor: Color,
defaultColor: Color,
defaultRadius: Dp,
selectedLength: Dp,
modifier: Modifier = Modifier.height(defaultRadius)
) {
val width by animateDpAsState(
targetValue = if (isSelected) selectedLength else defaultRadius,
animationSpec = spring(dampingRatio = Spring.DampingRatioMediumBouncy)
)
Box(
modifier = modifier
.width(width)
.clip(CircleShape)
.background(color = if (isSelected) selectedColor else defaultColor)
)
}
A copy-paste solution with as many customizations as I can think of.
Result
Usage
PageIndicator
PageIndicatorView
Also shared the same in this blog - Page Indicator with Jetpack Compose using Canvas and animations