Indicadores de progreso

Los indicadores de progreso muestran visualmente el estado de una operación. Usan el movimiento para llamar la atención del usuario qué tan cerca está la finalización del proceso, como la carga o el procesamiento de datos. También pueden indicar que se está procesando el procesamiento, sin hacer referencia a lo cerca que podría estar de completarse.

Considera estos tres casos de uso en los que podrías usar un indicador de progreso:

  • Carga de contenido: Mientras se recupera contenido de una red, como cuando se carga una imagen o datos para un perfil de usuario
  • Carga de archivos: Proporciona comentarios al usuario sobre cuánto tardará la carga.
  • Procesamiento prolongado: Cuando una app procesa una gran cantidad de datos, transmite al usuario qué parte del total está completo.

En Material Design, hay dos tipos de indicadores de progreso:

  • Determinado: Muestra exactamente cuánto progreso se realizó.
  • Indeterminate: Se anima continuamente sin tener en cuenta el progreso.

Del mismo modo, un indicador de progreso puede adoptar una de las siguientes formas:

  • Lineal: Es una barra horizontal que se llena de izquierda a derecha.
  • Circular: Es un círculo cuyo trazo crece en longitud hasta abarcar la circunferencia completa del círculo.
Un indicador de progreso lineal junto a un indicador de progreso circular
Figura 1: Los dos tipos de indicadores de progreso.

Plataforma de API

Aunque hay varios elementos componibles que puedes usar para crear botones de acción flotantes coherentes con Material Design, sus parámetros no difieren mucho. Entre los parámetros clave que debes tener en cuenta, se encuentran los siguientes:

  • progress: Es el progreso actual que muestra el indicador. Pasa un Float entre 0.0 y 1.0.
  • color: Es el color del indicador real. Es decir, la parte del componente que refleja el progreso y que lo abarca por completo cuando se completa el progreso.
  • trackColor: El color del recorrido sobre el que se dibuja el indicador.

Determina indicadores

Un indicador definido refleja exactamente qué tan completa es una acción. Usa los elementos que admiten composición LinearProgressIndicator o CircularProgressIndicator y pasa un valor para el parámetro progress.

En el siguiente fragmento, se proporciona un ejemplo relativamente detallado. Cuando el usuario presiona el botón, la app muestra el indicador de progreso y, luego, inicia una corrutina que aumenta gradualmente el valor de progress. Esto hace que el indicador de progreso se itere.

@Composable
fun LinearDeterminateIndicator() {
    var currentProgress by remember { mutableStateOf(0f) }
    var loading by remember { mutableStateOf(false) }
    val scope = rememberCoroutineScope() // Create a coroutine scope

    Column(
        verticalArrangement = Arrangement.spacedBy(12.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier.fillMaxWidth()
    ) {
        Button(onClick = {
            loading = true
            scope.launch {
                loadProgress { progress ->
                    currentProgress = progress
                }
                loading = false // Reset loading when the coroutine finishes
            }
        }, enabled = !loading) {
            Text("Start loading")
        }

        if (loading) {
            LinearProgressIndicator(
                progress = { currentProgress },
                modifier = Modifier.fillMaxWidth(),
            )
        }
    }
}

/** Iterate the progress value */
suspend fun loadProgress(updateProgress: (Float) -> Unit) {
    for (i in 1..100) {
        updateProgress(i.toFloat() / 100)
        delay(100)
    }
}

Cuando la carga se completa parcialmente, el indicador lineal del ejemplo anterior se muestra de la siguiente manera:

Del mismo modo, el indicador circular aparece de la siguiente manera:

Indicadores indeterminados

Un indicador indeterminado no refleja cuán cerca está de completarse una operación. En cambio, usa un movimiento para indicarle al usuario que el procesamiento está en curso, aunque sin especificar ningún grado de finalización.

Para crear un indicador de progreso indeterminado, usa el elemento componible LinearProgressIndicator o CircularProgressIndicator, pero no pases un valor para progress. En el siguiente ejemplo, se muestra cómo activar o desactivar un indicador indeterminado presionando un botón.

@Composable
fun IndeterminateCircularIndicator() {
    var loading by remember { mutableStateOf(false) }

    Button(onClick = { loading = true }, enabled = !loading) {
        Text("Start loading")
    }

    if (!loading) return

    CircularProgressIndicator(
        modifier = Modifier.width(64.dp),
        color = MaterialTheme.colorScheme.secondary,
        trackColor = MaterialTheme.colorScheme.surfaceVariant,
    )
}

El siguiente es un ejemplo de esta implementación cuando el indicador está activo:

El siguiente es un ejemplo de la misma implementación, pero con LinearProgressIndicator en lugar de CircularProgressIndicator.

Recursos adicionales