How to Implement CircularProgressIndicator in Jetpack Compose?

CircularProgressIndicator Jetpack Compose

Today, we will explore CircularProgressIndicator in Android Jetpack Compose with the help of examples.

Prerequisites:

There are two types of progress indicators – indeterminate and determinate.

Indeterminate Circular Progress Indicator:

It runs forever.

@Composable
fun CircularProgressIndicator(
    modifier: Modifier = Modifier,
    color: Color = MaterialTheme.colors.primary,
    strokeWidth: Dp = ProgressIndicatorDefaults.StrokeWidth
)

Here:

color – indicator’s color

strokeWidth – indicator’s width (thickness)

Example:

@Composable
fun MyUI() {
    CircularProgressIndicator(
        modifier = Modifier.size(size = 64.dp),
        color = Color.Magenta,
        strokeWidth = 6.dp
    )
}

Output:

Indeterminate Circular Progress Indicator

Determinate Circular Progress Indicator:

It is similar to the indeterminate indicator, but it takes an extra parameter called progress.

@Composable
fun MyUI() {
    CircularProgressIndicator(
        progress = 0.6f,
        modifier = Modifier.size(size = 64.dp),
        color = Color.Magenta,
        strokeWidth = 6.dp
    )
}

Output:

Determinate Circular Progress Indicator

The progress value ranges from 0f to 1f. 0f represents no progress, and 1f means 100% progress.

By default, you don’t see any animation. We can add a smooth animation by using animateFloatAsState API.

@Composable
fun MyUI() {

    // progress value 
    var progress by remember {
        mutableStateOf(0f) // initially 0f
    }

    // For animation
    val progressAnimate by animateFloatAsState(
        targetValue = progress,
        animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec
    )

    CircularProgressIndicator(
        progress = progressAnimate,
        modifier = Modifier.size(size = 64.dp),
        color = Color.Magenta,
        strokeWidth = 6.dp
    )

    // This is called when the Activity is launched
    LaunchedEffect(Unit) {
        progress = 0.6f
    }

    // Add space between indicator and button
    Spacer(modifier = Modifier.height(height = 16.dp))

    // Button
    Button(
        onClick = {
            progress = (0 until 100).random().toFloat() / 100
        },
        colors = ButtonDefaults.buttonColors(
            backgroundColor = Color.Magenta
        )
    ) {
        Text(
            text = "Random",
            color = Color.White
        )
    }
}

Output:

animations indicator

Instead of ProgressAnimationSpec, you can specify other animation spec functions.

By default, the indicator starts at the top center. We can change that by using the modifier’s rotate() function.

@Composable
fun MyUI() {

    CircularProgressIndicator(
        progress = 0.6f,
        modifier = Modifier
            .size(size = 64.dp)
            .rotate(degrees = 45f),
        color = Color.Magenta,
        strokeWidth = 6.dp
    )
}

Output:

Rotate indicator

The CircularProgressIndicator doesn’t offer many customizations. If you want to create your own indicator, use Canvas. Take a look at these beautiful custom progress bars made with Canvas.

Leave a Comment