android compose Checkbox 复选框 使用

android compose Checkbox 复选框 使用

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

  • 开启或关闭相应项目。
  • 从列表中的多个选项中进行选择。
  • 表示同意或接受。

复选框由以下元素组成:

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

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

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

说明

以下是您应注意的几个方面:

  • 状态管理
    • childCheckedStates:一个布尔值列表,使用 mutableStateOf() 跟踪每个子复选框的选中状态。
    • parentState:一个 ToggleableState,其值派生自子复选框的状态。
  • 界面组件
    • TriStateCheckbox:对于父复选框是必需的,因为它具有 state 参数,可让您将其设置为不确定状态。
    • Checkbox:用于每个子复选框,其状态与 childCheckedStates 中的相应元素相关联。
    • Text:显示标签和消息("全选""选项 X""已选择所有选项")。
  • 逻辑
    • 父复选框的 onClick 会将所有子复选框更新为与当前父状态相反的状态。
    • 每个子复选框的 onCheckedChange 都会更新 childCheckedStates 列表中的相应状态。
    • 当所有子复选框都处于选中状态时,代码会显示"All options selected"。
复制代码
package com.wn.androidcomposedemo1.basegoogle

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.material3.Checkbox
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TriStateCheckbox
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.state.ToggleableState
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.wn.androidcomposedemo1.ui.theme.AndroidComposeDemo1Theme

/**
 * Author : wn
 * Email : maoning20080808@163.com
 * Date : 2026/6/23 0:02
 * Description :
 */
class CheckBoxActivity : ComponentActivity(){

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            AndroidComposeDemo1Theme() {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    CheckBoxExample()
                }
            }
        }
    }

    @Preview
    @Composable
    fun CheckBoxExample(){
        Column() {
            Spacer(modifier = Modifier.height(20.dp))
            Text("复选框使用")
            Spacer(modifier = Modifier.height(50.dp))
            CheckBoxMinimalExample()
            Spacer(modifier = Modifier.height(50.dp))
            Text("有一个父复选框和一系列子复选框")
            CheckboxParentExample()
        }
    }

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

    @Preview
    @Composable
    fun CheckboxParentExample(){
        val childCheckedStates = remember { mutableStateListOf(false, false, false) }
        
        val parentState = when{
            childCheckedStates.all { it  } -> ToggleableState.On
            childCheckedStates.none { it } -> ToggleableState.Off
            else -> ToggleableState.Indeterminate
        }

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

            childCheckedStates.forEachIndexed { index, checked ->
                Row(
                    verticalAlignment = Alignment.CenterVertically
                ){
                    Text("Option ${index + 1}")

                    Checkbox(
                        checked = checked,
                        onCheckedChange = { isChecked ->
                            childCheckedStates[index] = isChecked
                        }
                    )
                }
            }
        }
    }
}