Skip to content

ProgressIndicator

ProgressIndicator is a progress indication component in COUI used to display the progress status of operations. It provides four styles: linear progress bar, circular progress indicator, infinite spinning indicator, and the rotating spinner, suitable for different loading and progress display scenarios.

Import

kotlin
import io.github.suqi8.coui.kmp.basic.LinearProgressIndicator // Linear progress bar
import io.github.suqi8.coui.kmp.basic.CircularProgressIndicator // Circular progress indicator
import io.github.suqi8.coui.kmp.basic.InfiniteProgressIndicator // Infinite spinning indicator
import io.github.suqi8.coui.kmp.basic.RotatingProgressIndicator // Rotating spinner

Basic Usage

Linear Progress Bar

Linear progress bar can be used to show operation progress:

kotlin
// Linear progress bar with determinate progress
var progress by remember { mutableStateOf(0.3f) }

LinearProgressIndicator(progress = progress)
kotlin
// Linear progress bar with indeterminate progress
LinearProgressIndicator()

Circular Progress Indicator

Circular progress indicator is suitable for space-saving scenarios:

kotlin
// Circular progress indicator with determinate progress
var progress by remember { mutableStateOf(0.7f) }

CircularProgressIndicator(progress = progress)
kotlin
// Circular progress indicator with indeterminate progress
CircularProgressIndicator()

Infinite Progress Indicator

Infinite progress indicator is suitable for scenarios where operation duration is uncertain. It is tinted with the theme accent color by default, matching the ColorOS "Refreshing…" spinner:

kotlin
InfiniteProgressIndicator()

Rotating Spinner

RotatingProgressIndicator is the ColorOS system-default indeterminate spinner: a bare stroked arc with flat caps and no background ring, whose sweep pulses between 273.6° and 50.4° while the arc spins twice per 1250 ms cycle. It is a direct port of the coui_rotating_loading.json asset that Theme.COUI binds to the couiRotatingSpinnerJsonName attribute, reproduced with a single drawArc so it needs no Lottie runtime.

kotlin
RotatingProgressIndicator()

It ships a default (26dp) and a small (16dp) tier, matching coui_lottie_loading_view_large_* and coui_lottie_loading_view_small_*:

kotlin
// Small rotating spinner
RotatingProgressIndicator(
    size = ProgressIndicatorDefaults.SmallRotatingProgressIndicatorSize,
    ringDiameter = ProgressIndicatorDefaults.SmallRotatingProgressIndicatorRingDiameter,
    strokeWidth = ProgressIndicatorDefaults.SmallRotatingProgressIndicatorStrokeWidth
)

Size Tiers

Circular and infinite indicators ship with a medium (default) and a large tier defined in ProgressIndicatorDefaults:

kotlin
// Large circular progress indicator
CircularProgressIndicator(
    size = ProgressIndicatorDefaults.LargeCircularProgressIndicatorSize,
    strokeWidth = ProgressIndicatorDefaults.LargeCircularProgressIndicatorStrokeWidth
)

// Large infinite progress indicator
InfiniteProgressIndicator(
    size = ProgressIndicatorDefaults.LargeInfiniteProgressIndicatorSize,
    strokeWidth = ProgressIndicatorDefaults.LargeInfiniteProgressIndicatorStrokeWidth
)

Component States

All progress indicator components support both determinate and indeterminate progress states:

Determinate Progress State

When a specific progress value (float between 0.0-1.0) is provided, the progress indicator shows exact progress:

kotlin
var progress by remember { mutableStateOf(0.6f) }

LinearProgressIndicator(progress = progress)
CircularProgressIndicator(progress = progress)

Indeterminate Progress State

When the progress value is null, the progress indicator shows an animation indicating an ongoing operation with unknown progress:

kotlin
LinearProgressIndicator(progress = null)
CircularProgressIndicator(progress = null)

Properties

LinearProgressIndicator Properties

Property NameTypeDescriptionDefault ValueRequired
modifierModifierModifier applied to the progress barModifierNo
progressFloat?Current progress value, null for indeterminatenullNo
colorsProgressIndicatorColorsColor configuration for the progress barProgressIndicatorDefaults.progressIndicatorColors()No
heightDpHeight of the progress barProgressIndicatorDefaults.DefaultLinearProgressIndicatorHeightNo

CircularProgressIndicator Properties

Property NameTypeDescriptionDefault ValueRequired
modifierModifierModifier applied to the progress indicatorModifierNo
progressFloat?Current progress value, null for indeterminatenullNo
colorsProgressIndicatorColorsColor configuration for the progress indicatorProgressIndicatorDefaults.circularProgressIndicatorColors()No
strokeWidthDpStroke width of the circular trackProgressIndicatorDefaults.DefaultCircularProgressIndicatorStrokeWidthNo
sizeDpSize of the circular indicatorProgressIndicatorDefaults.DefaultCircularProgressIndicatorSizeNo

InfiniteProgressIndicator Properties

Property NameTypeDescriptionDefault ValueRequired
modifierModifierModifier applied to the indicatorModifierNo
colorColorColor of the arcCOUITheme.colorScheme.primaryNo
sizeDpSize of the indicatorProgressIndicatorDefaults.DefaultInfiniteProgressIndicatorSizeNo
strokeWidthDpStroke width of the arcProgressIndicatorDefaults.DefaultInfiniteProgressIndicatorStrokeWidthNo

RotatingProgressIndicator Properties

Property NameTypeDescriptionDefault ValueRequired
modifierModifierModifier applied to the indicatorModifierNo
colorColorColor of the arcCOUITheme.colorScheme.onSurfaceContainerNo
sizeDpSize of the indicator's square view boxProgressIndicatorDefaults.DefaultRotatingProgressIndicatorSizeNo
ringDiameterDpDiameter of the arc's stroke centerlineProgressIndicatorDefaults.DefaultRotatingProgressIndicatorRingDiameterNo
strokeWidthDpStroke width of the arcProgressIndicatorDefaults.DefaultRotatingProgressIndicatorStrokeWidthNo

ProgressIndicatorDefaults Object

The ProgressIndicatorDefaults object provides default values and color configurations for progress indicator components.

Constants

Constant NameTypeDefault ValueDescription
DefaultLinearProgressIndicatorHeightDp4.dpDefault height of linear progress bar
DefaultCircularProgressIndicatorStrokeWidthDp3.dpDefault stroke width of circular indicator
DefaultCircularProgressIndicatorSizeDp30.dpDefault size of circular indicator
DefaultInfiniteProgressIndicatorStrokeWidthDp2.67.dpDefault stroke width of infinite indicator
DefaultInfiniteProgressIndicatorSizeDp18.dpDefault size of infinite indicator
LargeCircularProgressIndicatorStrokeWidthDp5.dpStroke width of the large circular tier
LargeCircularProgressIndicatorSizeDp40.dpSize of the large circular tier
LargeInfiniteProgressIndicatorStrokeWidthDp3.33.dpStroke width of the large infinite tier
LargeInfiniteProgressIndicatorSizeDp26.dpSize of the large infinite tier
DefaultRotatingProgressIndicatorSizeDp26.dpDefault view box size of the rotating spinner
DefaultRotatingProgressIndicatorRingDiameterDp24.14.dpDefault ring diameter of the rotating spinner
DefaultRotatingProgressIndicatorStrokeWidthDp1.857.dpDefault stroke width of the rotating spinner
SmallRotatingProgressIndicatorSizeDp16.dpView box size of the small rotating tier
SmallRotatingProgressIndicatorRingDiameterDp12.68.dpRing diameter of the small rotating tier
SmallRotatingProgressIndicatorStrokeWidthDp1.811.dpStroke width of the small rotating tier
MaxRotatingProgressIndicatorSizeDp40.dpLargest supported rotating spinner size

Methods

Method NameTypeDescription
progressIndicatorColors()ProgressIndicatorColorsCreates default color configuration for linear indicators
circularProgressIndicatorColors()ProgressIndicatorColorsCreates default color configuration for the circular indicator

ProgressIndicatorColors Class

Property NameTypeDescription
foregroundColorColorForeground color of the progress indicator
disabledForegroundColorColorForeground color when indicator is disabled
backgroundColorColorBackground color of the progress indicator

Advanced Usage

Custom Colored Linear Progress Bar

kotlin
var progress by remember { mutableStateOf(0.4f) }

LinearProgressIndicator(
    progress = progress,
    colors = ProgressIndicatorDefaults.progressIndicatorColors(
        foregroundColor = Color.Red,
        backgroundColor = Color.LightGray
    )
)

Resized Circular Progress Indicator

kotlin
var progress by remember { mutableStateOf(0.75f) }

CircularProgressIndicator(
    progress = progress,
    size = 50.dp,
    strokeWidth = 6.dp
)

Loading State with Button

kotlin
var isLoading by remember { mutableStateOf(false) }
val scope = rememberCoroutineScope()

Button(
    onClick = {
        isLoading = true
        // Simulate operation
        scope.launch {
            delay(2000)
            isLoading = false
        }
    },
    enabled = !isLoading
) {
     AnimatedVisibility(
        visible = isLoading
    ) {
        CircularProgressIndicator(
            modifier = Modifier
                .padding(end = 8.dp),
            size = 20.dp,
            strokeWidth = 4.dp
        )
    }
    Text("Submit")
}

Custom Infinite Progress Indicator

kotlin
InfiniteProgressIndicator(
    color = COUITheme.colorScheme.primary,
    size = 40.dp,
    strokeWidth = 3.dp
)

Loading State with Card

kotlin
var isLoading by remember { mutableStateOf(true) }

Card(
    modifier = Modifier
        .fillMaxWidth()
        .height(200.dp)
        .padding(16.dp)
) {
    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        if (isLoading) {
            Column(
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                CircularProgressIndicator()
                Spacer(modifier = Modifier.height(16.dp))
                Text("Loading...")
            }
        } else {
            Text("Content Loaded")
        }
    }
}
// Control loading state
LaunchedEffect(Unit) {
    delay(3000)
    isLoading = false
}

Changelog

Released under the Apache-2.0 License