New Compose Multiplatform components arrived on Composables UICheck it out →

CircularProgressIndicator

Material Design circular progress indicator.

Last updated:

Installation

dependencies {
   implementation("androidx.wear.compose:compose-material3:1.0.0-alpha23")
}

Overloads

@Composable
fun CircularProgressIndicator(
    progress: () -> Float,
    modifier: Modifier = Modifier,
    startAngle: Float = StartAngle,
    endAngle: Float = startAngle,
    colors: ProgressIndicatorColors = ProgressIndicatorDefaults.colors(),
    strokeWidth: Dp = StrokeWidth,
    gapSize: Dp = ProgressIndicatorDefaults.gapSize(strokeWidth),
)

Parameters

namedescription
progressThe progress of this progress indicator where 0.0 represents no progress and 1.0 represents completion. Values outside of this range are coerced into the range 0..1.
modifierModifier to be applied to the CircularProgressIndicator.
startAngleThe starting position of the progress arc, measured clockwise in degrees (0 to 360) from the 3 o'clock position. For example, 0 and 360 represent 3 o'clock, 90 and 180 represent 6 o'clock and 9 o'clock respectively. Default is 270 degrees [ProgressIndicatorDefaults.StartAngle] (top of the screen).
endAngleThe ending position of the progress arc, measured clockwise in degrees (0 to 360) from the 3 o'clock position. For example, 0 and 360 represent 3 o'clock, 90 and 180 represent 6 o'clock and 9 o'clock respectively. By default equal to [startAngle].
colors[ProgressIndicatorColors] that will be used to resolve the indicator and track color for this progress indicator in different states.
strokeWidthThe stroke width for the progress indicator.
gapSizeThe space left between the ends of the progress indicator and the track (in Dp).

Code Examples

FullScreenProgressIndicatorSample

@Composable
@Sampled
fun FullScreenProgressIndicatorSample() {
    Box(
        modifier =
        Modifier
            .background(MaterialTheme.colorScheme.background)
            .padding(FullScreenPadding)
            .fillMaxSize()
    ) {
        CircularProgressIndicator(
            progress = { 0.25f },
            startAngle = 120f,
            endAngle = 60f,
            colors = ProgressIndicatorDefaults.colors(
                indicatorColor = Color.Green,
                trackColor = Color.Green.copy(alpha = 0.5f)
            ),
        )
    }
}

OverflowProgressIndicatorSample

@Composable
@Sampled
fun OverflowProgressIndicatorSample() {
    Box(
        modifier =
        Modifier
            .background(MaterialTheme.colorScheme.background)
            .padding(FullScreenPadding)
            .fillMaxSize()
    ) {
        CircularProgressIndicator(
            // The progress is limited by 100%, 120% ends up being 20% with the track brush
            // indicating overflow.
            progress = { 0.2f },
            startAngle = 120f,
            endAngle = 60f,
            colors = ProgressIndicatorDefaults.colors(
                trackBrush = Brush.linearGradient(
                    listOf(
                        MaterialTheme.colorScheme.primary,
                        MaterialTheme.colorScheme.surfaceContainer
                    )
                )
            )
        )
    }
}

MediaButtonProgressIndicatorSample

@Composable
@Sampled
fun MediaButtonProgressIndicatorSample() {
    var isPlaying by remember {
        mutableStateOf(false)
    }
    val progressPadding = 4.dp

    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(MaterialTheme.colorScheme.background)
    ) {

        Box(
            modifier = Modifier
                .align(Alignment.Center)
                .size(IconButtonDefaults.DefaultButtonSize + progressPadding)
        ) {
            CircularProgressIndicator(progress = { 0.75f }, strokeWidth = progressPadding)
            IconButton(
                modifier = Modifier
                    .align(Alignment.Center)
                    .padding(progressPadding)
                    .clip(CircleShape)
                    .background(MaterialTheme.colorScheme.surfaceContainerLow),
                onClick = { isPlaying = !isPlaying }
            ) {
                Icon(
                    imageVector = if (isPlaying) Icons.Filled.Close else Icons.Filled.PlayArrow,
                    contentDescription = "Play/pause button icon"
                )
            }
        }
    }
}