Поле для флажка

Флажки позволяют пользователям выбирать один или несколько элементов из списка. Флажок можно использовать, чтобы позволить пользователю:

  • Включите или отключите нужный пункт.
  • Выбрать несколько вариантов из списка.
  • Выразите согласие или одобрение.

Анатомия

Флажок состоит из следующих элементов:

  • Флажок. Это контейнер для флажка.
  • Флажок. Визуальный индикатор, который показывает, установлен ли флажок.
  • Ярлык. Текст, описывающий флажок.

Штаты

Флажок может находиться в одном из трех состояний:

  • Не выбрано. Флажок не установлен. Коробка пуста.
  • Неопределенный. Флажок находится в неопределенном состоянии. В поле стоит тире.
  • Выбрано. Флажок установлен. В поле есть флажок.

На изображении ниже показаны три состояния флажка.

Пример компонента флажка в каждом из трех состояний: не выбрано, выбрано и неопределенно.
Рисунок 1. Три состояния флажка. "Не выбрано", "Не определено" и "Выбрано".

Реализация

Чтобы создать флажок в приложении, используйте composable-функцию Checkbox. Вот несколько основных параметров, о которых нужно помнить:

  • checked – логическое значение, которое определяет, установлен ли флажок.
  • onCheckedChange() – функция, которую вызывает приложение, когда пользователь нажимает на флажок.

В следующем фрагменте кода показано, как использовать composable-функцию Checkbox:

@Composable
fun CheckboxMinimalExample() {
    var checked by remember { mutableStateOf(true) }

    Row(
        verticalAlignment = Alignment.CenterVertically,
    ) {
        Text(
            "Minimal checkbox"
        )
        Checkbox(
            checked = checked,
            onCheckedChange = { checked = it }
        )
    }

    Text(
        if (checked) "Checkbox is checked" else "Checkbox is unchecked"
    )
}

Описание

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

Результат

Если флажок не установлен, будет создан следующий компонент:

Снятый флажок с ярлыком. Под ним написано "Флажок не установлен".
Рисунок 2. Снятый флажок

А вот как выглядит тот же флажок, когда он установлен:

Установленный флажок с ярлыком. Текст под ним гласит: "Флажок установлен".
Рисунок 3. Установленный флажок

Расширенный пример

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

@Composable
fun CheckboxParentExample() {
    // Initialize states for the child checkboxes
    val childCheckedStates = remember { mutableStateListOf(false, false, false) }

    // Compute the parent state based on children's states
    val parentState = when {
        childCheckedStates.all { it } -> ToggleableState.On
        childCheckedStates.none { it } -> ToggleableState.Off
        else -> ToggleableState.Indeterminate
    }

    Column {
        // Parent TriStateCheckbox
        Row(
            verticalAlignment = Alignment.CenterVertically,
        ) {
            Text("Select all")
            TriStateCheckbox(
                state = parentState,
                onClick = {
                    // Determine new state based on current state
                    val newState = parentState != ToggleableState.On
                    childCheckedStates.forEachIndexed { index, _ ->
                        childCheckedStates[index] = newState
                    }
                }
            )
        }

        // Child Checkboxes
        childCheckedStates.forEachIndexed { index, checked ->
            Row(
                verticalAlignment = Alignment.CenterVertically,
            ) {
                Text("Option ${index + 1}")
                Checkbox(
                    checked = checked,
                    onCheckedChange = { isChecked ->
                        // Update the individual child state
                        childCheckedStates[index] = isChecked
                    }
                )
            }
        }
    }

    if (childCheckedStates.all { it }) {
        Text("All options selected")
    }
}

Описание

Обратите внимание на следующие моменты:

  • Управление состоянием:
    • childCheckedStates – список логических значений, в котором используется mutableStateOf(), чтобы отслеживать состояние каждого дочернего флажка.
    • parentState: ToggleableState, значение которого зависит от состояния дочерних флажков.
  • Компоненты интерфейса:
    • TriStateCheckbox – необходим для родительского флажка, так как у него есть параметр state, который позволяет задать неопределенное состояние.
    • Checkbox – используется для каждого дочернего флажка, состояние которого связано с соответствующим элементом в childCheckedStates.
    • Text: показывает ярлыки и сообщения ("Выбрать все", "Вариант X", "Выбраны все варианты").
  • Логика
    • onClick родительского флажка обновляет все дочерние флажки, устанавливая для них значение, противоположное текущему значению родительского флажка.
    • Каждый дочерний флажок onCheckedChange обновляет соответствующее состояние в списке childCheckedStates.
    • Если все дочерние флажки установлены, код возвращает значение All options selected.

Результат

В этом примере получается следующий компонент, когда все флажки сняты.

Серия флажков с ярлыками, флажки не установлены.
Рисунок 4. Снятые флажки

А вот как выглядит компонент, когда выбраны все варианты, например когда пользователь нажимает "Выбрать все":

Ряд флажков с метками и ярлыком. Первый – "Выбрать все". Под ними находится текстовый компонент с надписью "Выбраны все варианты".
Рисунок 5. Установленные флажки

Если установлен только один флажок, родительский флажок отображается в неопределенном состоянии:

Серия флажков с ярлыками, флажки не установлены. Будет выбран один вариант. Флажок "Выбрать все" находится в неопределенном состоянии, в нем отображается тире.
Рисунок 6. Неопределенный флажок

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