Build apps faster with our new App builder! Check it out →

CircularProgressIndicator

Android

Component in Wear Material 3 Compose

Material Design circular progress indicator.

Last updated:

Installation

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

Overloads

@Composable
fun CircularProgressIndicator(
    progress: () -> Float,
    modifier: Modifier = Modifier,
    allowProgressOverflow: Boolean = false,
    startAngle: Float = CircularProgressIndicatorDefaults.StartAngle,
    endAngle: Float = startAngle,
    colors: ProgressIndicatorColors = ProgressIndicatorDefaults.colors(),
    strokeWidth: Dp = CircularProgressIndicatorDefaults.largeStrokeWidth,
    gapSize: Dp = CircularProgressIndicatorDefaults.calculateRecommendedGapSize(strokeWidth),
    enabled: Boolean = true,
)

Parameters

namedescription
progressThe progress of this progress indicator where 0.0 represents no progress and 1.0 represents completion.
modifierModifier to be applied to the CircularProgressIndicator.
allowProgressOverflowWhen progress overflow is allowed, values smaller than 0.0 will be coerced to 0, while values larger than 1.0 will be wrapped around and shown as overflow with a different track color [ProgressIndicatorColors.overflowTrackBrush]. For example values 1.2, 2.2 etc will be shown as 20% progress with the overflow color. When progress overflow is not allowed, progress values will be coerced into the range 0..1.
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 [CircularProgressIndicatorDefaults.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. The recommended values are [CircularProgressIndicatorDefaults.largeStrokeWidth] and [CircularProgressIndicatorDefaults.smallStrokeWidth].
gapSizeThe size (in Dp) of the gap between the ends of the progress indicator and the track. The stroke endcaps are not included in this distance.
enabledcontrols the enabled state. Although this component is not clickable, it can be contained within a clickable component. When enabled is false, this component will appear visually disabled.
@Composable
fun CircularProgressIndicator(
    modifier: Modifier = Modifier,
    colors: ProgressIndicatorColors = ProgressIndicatorDefaults.colors(),
    strokeWidth: Dp = CircularProgressIndicatorDefaults.IndeterminateStrokeWidth,
    gapSize: Dp = CircularProgressIndicatorDefaults.calculateRecommendedGapSize(strokeWidth),
)

Parameters

namedescription
modifierModifier to be applied to the CircularProgressIndicator.
colors[ProgressIndicatorColors] that will be used to resolve the indicator and track color for this progress indicator.
strokeWidthThe stroke width for the progress indicator. The recommended values is [CircularProgressIndicatorDefaults.IndeterminateStrokeWidth].
gapSizeThe size (in Dp) of the gap between the ends of the progress indicator and the track. The stroke endcaps are not included in this distance.

Code Examples

FullScreenProgressIndicatorSample

@Composable
fun FullScreenProgressIndicatorSample() {
    Box(
        modifier =
            Modifier.background(MaterialTheme.colorScheme.background)
                .padding(CircularProgressIndicatorDefaults.FullScreenPadding)
                .fillMaxSize()
    ) {
        CircularProgressIndicator(
            progress = { 0.25f },
            startAngle = 120f,
            endAngle = 60f,
        )
    }
}

OverflowProgressIndicatorSample

@Composable
fun OverflowProgressIndicatorSample() {
    Box(
        modifier =
            Modifier.background(MaterialTheme.colorScheme.background)
                .padding(CircularProgressIndicatorDefaults.FullScreenPadding)
                .fillMaxSize()
    ) {
        CircularProgressIndicator(
            // Overflow value of 120%
            progress = { 1.2f },
            allowProgressOverflow = true,
            startAngle = 120f,
            endAngle = 60f,
        )
    }
}

MediaButtonProgressIndicatorSample

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

    Box(modifier = Modifier.fillMaxSize().background(MaterialTheme.colorScheme.background)) {
        Box(
            modifier =
                Modifier.align(Alignment.Center)
                    .size(IconButtonDefaults.DefaultButtonSize + progressPadding)
        ) {
            CircularProgressIndicator(progress = { progress }, strokeWidth = progressPadding)
            IconButton(
                modifier =
                    Modifier.align(Alignment.Center)
                        .semantics {
                            // Set custom progress semantics for accessibility.
                            contentDescription =
                                String.format(
                                    "Play/pause button, track progress: %.0f%%",
                                    progress * 100
                                )
                        }
                        .padding(progressPadding)
                        .clip(CircleShape)
                        .background(MaterialTheme.colorScheme.surfaceContainerLow),
                onClick = { isPlaying = !isPlaying }
            ) {
                Icon(
                    imageVector = if (isPlaying) Icons.Filled.Close else Icons.Filled.PlayArrow,
                    contentDescription = null,
                )
            }
        }
    }
}

SmallValuesProgressIndicatorSample

@Composable
fun SmallValuesProgressIndicatorSample() {
    Box {
        CircularProgressIndicator(
            // Small progress values like 2% will be rounded up to at least the stroke width.
            progress = { 0.02f },
            modifier =
                Modifier.fillMaxSize().padding(CircularProgressIndicatorDefaults.FullScreenPadding),
            startAngle = 120f,
            endAngle = 60f,
            strokeWidth = 10.dp,
            colors =
                ProgressIndicatorDefaults.colors(
                    indicatorColor = Color.Green,
                    trackColor = Color.White
                ),
        )
    }
}

IndeterminateProgressIndicatorSample

@Composable
fun IndeterminateProgressIndicatorSample() {
    Box(modifier = Modifier.fillMaxSize()) {
        CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
    }
}
by @alexstyl