Gli indicatori di avanzamento mostrano visivamente lo stato di un'operazione. Utilizzano il movimento per attirare l'attenzione dell'utente sulla fase di completamento del processo, ad esempio il caricamento o l'elaborazione dei dati. Possono anche indicare che l'elaborazione è in corso, senza fare riferimento a quanto manca al completamento.
Considera questi tre casi d'uso in cui potresti utilizzare un indicatore di avanzamento:
- Caricamento di contenuti: durante il recupero di contenuti da una rete, ad esempio il caricamento di un'immagine o di dati per il profilo di un utente.
- Caricamento file: fornisci all'utente un feedback sul tempo necessario per il caricamento.
- Elaborazione lunga: mentre un'app elabora una grande quantità di dati, comunicate all'utente la percentuale di completamento del totale.
In Material Design esistono due tipi di indicatori di avanzamento:
- Determinato: mostra esattamente il progresso compiuto.
- Indeterminate: l'animazione viene visualizzata continuamente, indipendentemente dall'avanzamento.
Analogamente, un indicatore di avanzamento può avere una delle due seguenti forme:
- Lineare: una barra orizzontale che si riempie da sinistra a destra.
- Circolare: un cerchio il cui tratto aumenta di lunghezza fino a comprendere la circonferenza completa del cerchio.
API Surface
Sebbene esistano diversi composabili che puoi utilizzare per creare indicatori di avanzamento in linea con Material Design, i relativi parametri non differiscono molto. Tra i parametri chiave da tenere presenti, figurano i seguenti:
progress
: l'avanzamento corrente visualizzato dall'indicatore. Passa un valoreFloat
compreso tra0.0
e1.0
.color
: il colore dell'indicatore effettivo. ovvero la parte del componente che riflette l'avanzamento e che lo racchiude completamente al termine dell'avanzamento.trackColor
: il colore del canale su cui viene disegnato l'indicatore.
Determinati indicatori
Un determinato indicatore riflette esattamente il grado di completezza di un'azione. Utilizza i composabili LinearProgressIndicator
o CircularProgressIndicator
e passa un valore per il parametro progress
.
Lo snippet seguente fornisce un esempio relativamente dettagliato. Quando l'utente preme il pulsante, l'app mostra l'indicatore di avanzamento e avvia una coroutine che aumenta gradualmente il valore di progress
. Di conseguenza, l'indicatore di avanzamento viene visualizzato in ordine crescente.
@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) } }
Quando il caricamento è parzialmente completato, l'indicatore lineare nell'esempio precedente viene visualizzato come segue:
Analogamente, l'indicatore circolare viene visualizzato come segue:
Indicatori indefiniti
Un indicatore indeterminato non riflette il livello di completamento di un'operazione. Utilizza piuttosto il movimento per indicare all'utente che l'elaborazione è in corso, anche se senza specificare alcun grado di completamento.
Per creare un indicatore di avanzamento indeterminato, utilizza il composable LinearProgressIndicator
o CircularProgressIndicator
, ma non passare un valore per progress
. L'esempio seguente mostra come attivare/disattivare un indicatore indeterminato premendo un pulsante.
@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, ) }
Di seguito è riportato un esempio di questa implementazione quando l'indicatore è attivo:
Di seguito è riportato un esempio della stessa implementazione, ma con LinearProgressIndicator
anziché CircularProgressIndicator
.