CircularProgressIndicator
Composable Component
Material Design circular progress indicator. Progress changes are animated.
Android
@Composable
public fun CircularProgressIndicator(
progress: () -> Float,
modifier: Modifier = Modifier,
enabled: Boolean = true,
allowProgressOverflow: Boolean = false,
startAngle: Float = CircularProgressIndicatorDefaults.StartAngle,
endAngle: Float = startAngle,
colors: ProgressIndicatorColors = ProgressIndicatorDefaults.colors(),
strokeWidth: Dp = CircularProgressIndicatorDefaults.largeStrokeWidth,
gapSize: Dp = CircularProgressIndicatorDefaults.calculateRecommendedGapSize(strokeWidth),
)
Parameters
| progress | The progress of this progress indicator where 0.0 represents no progress and 1.0 represents completion. Progress changes will be animated. |
| modifier | Modifier to be applied to the CircularProgressIndicator. |
| enabled | controls 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. |
| allowProgressOverflow | When 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. |
| startAngle | The 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). |
| endAngle | The 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. |
| strokeWidth | The stroke width for the progress indicator. The recommended values are CircularProgressIndicatorDefaults.largeStrokeWidth and CircularProgressIndicatorDefaults.smallStrokeWidth. |
| gapSize | The 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. |
Android
@Composable
public fun CircularProgressIndicator(
modifier: Modifier = Modifier,
colors: ProgressIndicatorColors = ProgressIndicatorDefaults.colors(),
strokeWidth: Dp = CircularProgressIndicatorDefaults.IndeterminateStrokeWidth,
gapSize: Dp = CircularProgressIndicatorDefaults.calculateRecommendedGapSize(strokeWidth),
)
Parameters
| modifier | Modifier to be applied to the CircularProgressIndicator. |
| colors | ProgressIndicatorColors that will be used to resolve the indicator and track color for this progress indicator. |
| strokeWidth | The stroke width for the progress indicator. The recommended values is CircularProgressIndicatorDefaults.IndeterminateStrokeWidth. |
| gapSize | The 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)
}
}
IndeterminateProgressIndicatorSample
@Composable
fun IndeterminateProgressIndicatorSample() {
Box(modifier = Modifier.fillMaxSize()) {
CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
}
}
MediaButtonProgressIndicatorSample
@Composable
fun MediaButtonProgressIndicatorSample() {
var isPlaying by remember { mutableStateOf(false) }
val buttonPadding = 4.dp
val progressStrokeWidth = 4.dp
val progress = 0.75f
Box(modifier = Modifier.fillMaxSize().background(MaterialTheme.colorScheme.background)) {
// The CircularProgressIndicator should be around the IconButton, with an extra gap between
// then of 'buttonPadding'. We multiply by 2 because the size includes progressStrokeWidth
// at top and bottom and the buttonPadding at top and bottom.
CircularProgressIndicator(
modifier =
Modifier.align(Alignment.Center)
.size(
IconButtonDefaults.DefaultButtonSize +
progressStrokeWidth * 2 +
buttonPadding * 2
),
progress = { progress },
strokeWidth = progressStrokeWidth,
)
IconButton(
modifier =
Modifier.align(Alignment.Center)
.semantics {
// Set custom progress semantics for accessibility.
contentDescription =
String.format(
"Play/pause button, track progress: %.0f%%",
progress * 100,
)
}
.clip(CircleShape)
.background(MaterialTheme.colorScheme.surfaceContainerLow),
onClick = { isPlaying = !isPlaying },
) {
Icon(
imageVector = if (isPlaying) Icons.Filled.Close else Icons.Filled.PlayArrow,
contentDescription = null,
)
}
}
}
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,
)
}
}
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,
),
)
}
}