Индикаторы выполнения визуально показывают статус операции. Они используют движение, чтобы привлечь внимание пользователя к тому, насколько близок процесс к завершению, например, загрузка или обработка данных. Они также могут указывать на то, что обработка выполняется, без указания на то, насколько она близка к завершению.
Рассмотрим три варианта использования индикатора выполнения:
- Загрузка контента. При получении контента из сети, например при загрузке изображения или данных для профиля пользователя.
- Загрузка файла. Сообщите пользователю, сколько времени может занять загрузка.
- Длительная обработка. Если приложение обрабатывает большой объем данных, покажите пользователю, какая часть работы уже выполнена.
В Material Design есть два типа индикаторов выполнения:
- Определенный. Показывает, сколько именно выполнено.
- Неопределенный. Анимация воспроизводится непрерывно, независимо от прогресса.
Индикатор выполнения может быть двух видов:
- Линейный. Горизонтальная полоса, которая заполняется слева направо.
- Круг. Круг, обводка которого увеличивается, пока не охватит всю окружность.
API Surface
Хотя для создания индикаторов прогресса в соответствии с Material Design можно использовать несколько composable-функций, их параметры не сильно различаются. Вот основные параметры, которые следует учитывать:
progress– текущий прогресс, который показывает индикатор. Передайте значениеFloatв диапазоне от0.0до1.0.color– цвет индикатора. То есть часть компонента, которая отражает прогресс и которая полностью охватывает компонент, когда прогресс завершен.trackColor– цвет дорожки, на которой нарисован индикатор.
Определенные индикаторы
Определенный индикатор точно отражает, насколько завершено действие. Используйте composable-функцию LinearProgressIndicator или CircularProgressIndicator и передайте значение для параметра progress.
Ниже приведен подробный пример. Когда пользователь нажимает кнопку, приложение показывает индикатор выполнения и запускает сопрограмму, которая постепенно увеличивает значение progress. Это заставляет индикатор прогресса
повторяться по очереди.
@Composable fun LinearDeterminateIndicator() { var currentProgress by remember { mutableFloatStateOf(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) } }
Когда загрузка частично завершена, линейный индикатор в предыдущем примере выглядит следующим образом:
Круглый индикатор выглядит следующим образом:
Индикаторы неопределенного состояния
Индикатор неопределенного состояния не отражает, насколько близко к завершению находится операция. Вместо этого он использует движение, чтобы указать пользователю, что обработка продолжается, хотя и без указания какой-либо степени завершения.
Чтобы создать неопределенный индикатор выполнения, используйте composable-функцию LinearProgressIndicator или CircularProgressIndicator, но не передавайте значение для progress. В следующем примере показано, как можно переключать неопределенный индикатор нажатием кнопки.
@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, ) }
Ниже приведен пример реализации, когда индикатор активен.
Ниже приведен пример той же реализации, но с LinearProgressIndicator вместо CircularProgressIndicator.