复选框

复选框可让用户从列表中选择一个或多个项目。您可以使用复选框让用户执行以下操作:

  • 开启或关闭某项内容。
  • 从列表中的多个选项中进行选择。
  • 表明同意或接受。

解剖学

复选框由以下元素组成:

  • Box:这是复选框的容器。
  • 勾选:这是用于显示复选框是否已选中的视觉指示器。
  • 标签:用于描述复选框的文本。

状态

复选框可能处于以下三种状态之一:

  • 未选中:复选框未选中。该框为空。
  • 不确定:复选框处于不确定状态。该框包含短划线。
  • 已选中:复选框处于选中状态。该方框包含一个对勾标记。

下图展示了复选框的三种状态。

复选框组件在三种状态(未选中、选中和未确定)下的示例。
图 1. 复选框的三种状态。未选中、未确定和已选中。

实现

您可以使用 Checkbox 可组合项在应用中创建复选框。只需记住几个关键参数即可:

  • checked:用于捕获复选框是否已选中或未选中的布尔值。
  • onCheckedChange():应用在用户点按复选框时调用的函数。

以下代码段演示了如何使用 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 lambda 会更新 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. 未确定复选框

其他资源