Compose Unstyled 2.0 is out! Check the official announcement blog ->

Progress Indicator

A progress indicator component for determinate and indeterminate loading states.

import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.composeunstyled.Indicator
import com.composeunstyled.UnstyledProgress
import kotlinx.coroutines.delay
import kotlin.time.Duration.Companion.milliseconds

@Composable
fun ProgressIndicatorDemo() {
  var hasProgressed by remember { mutableStateOf(false) }

  val progress by animateFloatAsState(
    targetValue = if (hasProgressed) 0.85f else 0.2f,
    animationSpec = tween(durationMillis = 450),
  )
  LaunchedEffect(Unit) {
    delay(500.milliseconds)
    hasProgressed = true
  }

  UnstyledProgress(
    progress = progress,
    modifier = Modifier
      .width(400.dp)
      .height(12.dp)
      .clip(RoundedCornerShape(100))
      .background(Color(0xFFF8FAFC), RoundedCornerShape(100))
      .border(1.dp, Color(0xFFCACACA), RoundedCornerShape(100)),
  ) {
    Indicator(Modifier.background(Color.Black, RoundedCornerShape(100)))
  }
}

Installation

implementation("com.composables:composeunstyled-progress")

Anatomy

UnstyledProgress(progress = progress) {
  Indicator()
}

Concepts

  • UnstyledProgress() represents the visible bounds of the progress including the track.
  • Indicator fills the available width by the current progress value.

Accessibility

UnstyledProgress applies the appropriate accessibility semantics based on whether the progress parameter is provided.

Code Examples

Creating a determinate progress indicator

Use the progress parameter when the current progress value is known:

UnstyledProgress(progress = 0.4f) {
  Indicator()
}

Creating an indeterminate progress indicator

Use the overload without the progress parameter when the current progress value is unknown:

UnstyledProgress {
  BasicText("Loading")
}

Drawing a custom indicator

Use the ProgressScope.progress property when the indicator needs custom measurement:

UnstyledProgress(progress = progress) {
  Box(Modifier.fillMaxWidth(progress))
}

API Reference

UnstyledProgress

Parameter Type Description
progress Float (Optional) A float value between 0 and 1 representing the progress. Skipping this value treats the progress as indeterminate for accessibility purposes.
modifier Modifier Modifier to be applied to the progress container.
content ProgressScope.() -> Unit A composable function that defines the content of the progress indicator.
content () -> Unit A composable function that defines the content of the progress indicator.

ProgressScope

Parameter Type Description
progress Float (Optional) A float value between 0 and 1 representing the progress. Skipping this value treats the progress as indeterminate for accessibility purposes.

ProgressScope.Indicator

Parameter Type Description
modifier Modifier Modifier to apply to the filled progress content.