Caixa de seleção

As caixas de seleção permitem que os usuários selecionem um ou mais itens de uma lista. Você pode usar uma caixa de seleção para permitir que o usuário faça o seguinte:

  • Ativar ou desativar um item.
  • Selecione entre várias opções em uma lista.
  • Indicar concordância ou aceitação.

Anatomia

Uma caixa de seleção consiste nos seguintes elementos:

  • Box: é o contêiner da caixa de seleção.
  • Verificar: é o indicador visual que mostra se a caixa de seleção está selecionada ou não.
  • Rótulo: é o texto que descreve a caixa de seleção.

Estados

Uma caixa de seleção pode estar em um dos três estados a seguir:

  • Desmarcada: a caixa de seleção não está marcada. A caixa está vazia.
  • Indeterminado: a caixa de seleção está em um estado indeterminado. A caixa contém um traço.
  • Selecionada: a caixa de seleção está marcada. A caixa contém uma marca de seleção.

A imagem a seguir demonstra os três estados de uma caixa de seleção.

Exemplo de um componente de caixa de seleção em cada um dos três estados: não selecionado, selecionado e indeterminado.
Figura 1. Os três estados de uma caixa de seleção. Não selecionado, indeterminado e selecionado.

Implementação

Você pode usar o elemento combinável Checkbox para criar uma caixa de seleção no seu app. Há alguns parâmetros importantes que precisam ser considerados:

  • checked: o booleano que captura se a caixa de seleção está marcada ou desmarcada.
  • onCheckedChange(): a função chamada pelo app quando o usuário toca na caixa de seleção.

O snippet abaixo demonstra como usar o elemento combinável 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"
    )
}

Explicação

Esse código cria uma caixa de seleção que inicialmente está desmarcada. Quando o usuário clica na caixa de seleção, o lambda onCheckedChange atualiza o estado checked.

Resultado

Este exemplo produz o seguinte componente quando desmarcado:

Uma caixa de seleção desmarcada com um marcador. O texto abaixo dela diz "A caixa de seleção está desmarcada".
Figura 2. Caixa de seleção desmarcada

E esta é a aparência da mesma caixa de seleção quando marcada:

Uma caixa de seleção marcada com um rótulo. O texto abaixo diz "A caixa de seleção está marcada".
Figura 3. Caixa de seleção marcada

Exemplo avançado

Confira a seguir um exemplo mais complexo de como implementar caixas de seleção no seu app. Neste snippet, há uma caixa de seleção mãe e uma série de caixas secundárias. Quando o usuário toca na caixa de seleção pai, o app marca todas as caixas de seleção filhas.

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

Explicação

Confira a seguir alguns pontos que você precisa observar neste exemplo:

  • Gerenciamento de estado:
    • childCheckedStates: uma lista de booleanos que usam mutableStateOf() para rastrear o estado de verificação de cada caixa de seleção filha.
    • parentState: um ToggleableState cujo valor é derivado dos estados das caixas de seleção filhas.
  • Componentes da interface:
    • TriStateCheckbox: é necessário para a caixa de seleção pai, porque ela tem um parâmetro state que permite definir como indeterminado.
    • Checkbox: usado para cada caixa de seleção filha com o estado vinculado ao elemento correspondente em childCheckedStates.
    • Text: exibe rótulos e mensagens ("Selecionar tudo", "Opção X", "Todas as opções selecionadas").
  • Lógica:
    • O onClick da caixa de seleção mãe atualiza todas as caixas de seleção filhas para o estado oposto ao atual.
    • O onCheckedChange de cada caixa de seleção filha atualiza o estado correspondente na lista childCheckedStates.
    • O código mostra "All options selected" quando todas as caixas de seleção filhas estão marcadas.

Resultado

Este exemplo produz o componente a seguir quando todas as caixas de seleção estão desmarcadas.

Uma série de caixas de seleção marcadas com um rótulo.
Figura 4. Caixas de seleção desmarcadas.

Da mesma forma, é assim que o componente aparece quando todas as opções são marcadas, como quando o usuário toca em "Selecionar tudo":

Uma série de caixas de seleção marcadas com rótulos e um rótulo. O primeiro é marcado como "selecionar tudo". Há um componente de texto abaixo deles que diz "todas as opções selecionadas".
Figura 5. Caixas de seleção marcadas

Quando apenas uma opção é marcada, a caixa de seleção pai exibe o estado indeterminado:

Uma série de caixas de seleção desmarcadas com um rótulo. Todos os itens estão desmarcados, exceto um. A caixa de seleção "Selecionar tudo" está indefinida e exibe um traço.
Figura 6. Caixa de seleção indeterminada

Outros recursos