Индикаторы прогресса

Индикаторы хода выполнения визуально отображают статус операции. Они используют движение, чтобы привлечь внимание пользователя к тому, насколько близок к завершению процесс, например, загрузка или обработка данных. Они также могут сигнализировать о ходе обработки, независимо от того, насколько она близка к завершению.

Рассмотрим эти три варианта использования индикатора прогресса:

  • Загрузка контента : при извлечении контента из сети, например при загрузке изображения или данных для профиля пользователя.
  • Загрузка файла : сообщите пользователю, сколько времени может занять загрузка.
  • Длительная обработка : пока приложение обрабатывает большой объем данных, сообщите пользователю, какая часть процесса уже выполнена.

В Material Design существует два типа индикаторов прогресса:

  • Определить : Отображает точный прогресс, достигнутый в ходе выполнения.
  • Неопределенный : Оживляется непрерывно, независимо от прогресса.

Аналогично индикатор прогресса может принимать одну из двух следующих форм:

  • Линейный : горизонтальная полоса, заполняющаяся слева направо.
  • Круговой : круг, штрих которого увеличивается в длину до тех пор, пока не охватит всю окружность круга.
Линейный индикатор прогресса и круговой индикатор прогресса.
Рисунок 1. Два типа индикаторов прогресса.

API-поверхность

Хотя существует несколько компонуемых объектов, которые можно использовать для создания индикаторов прогресса в соответствии с Material Design, их параметры не сильно отличаются. Среди ключевых параметров, которые следует учитывать, следующие:

  • progress : Текущий прогресс, отображаемый индикатором. Передайте Float от 0.0 до 1.0 .
  • color : цвет фактического индикатора. То есть той части компонента, которая отражает ход выполнения и которая полностью охватывает компонент после завершения выполнения.
  • trackColor : Цвет дорожки, на которой отображается индикатор.

Определенные показатели

Определённый индикатор точно отражает степень завершения действия. Используйте составные элементы LinearProgressIndicator или CircularProgressIndicator и передайте значение параметра progress .

Следующий фрагмент кода представляет собой довольно подробный пример. Когда пользователь нажимает кнопку, приложение отображает индикатор прогресса и запускает сопрограмму, которая постепенно увеличивает значение progress . Это приводит к тому, что индикатор прогресса поочередно увеличивается.

@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)
    }
}

Когда загрузка частично завершена, линейный индикатор в предыдущем примере выглядит следующим образом:

Аналогично круговой индикатор выглядит следующим образом:

Неопределенные индикаторы

Неопределённый индикатор не отражает, насколько близка к завершению операция. Вместо этого он использует движение, чтобы показать пользователю, что обработка продолжается, хотя и без указания степени завершения.

Чтобы создать неопределённый индикатор хода выполнения, используйте компонуемый объект 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 .

Дополнительные ресурсы