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

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

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

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

В 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 .

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