Hộp đánh dấu

Hộp đánh dấu cho phép người dùng chọn một hoặc nhiều mục trong danh sách. Bạn có thể sử dụng hộp đánh dấu để cho phép người dùng làm những việc sau:

  • Bật hoặc tắt một mục.
  • Chọn trong số nhiều lựa chọn trong danh sách.
  • Cho biết sự đồng ý hoặc chấp nhận.

Phân tích

Hộp đánh dấu bao gồm các phần tử sau:

  • Box (Hộp): Đây là vùng chứa cho hộp đánh dấu.
  • Đánh dấu: Đây là chỉ báo trực quan cho biết liệu hộp đánh dấu có được chọn hay không.
  • Nhãn: Đây là văn bản mô tả hộp đánh dấu.

Các trạng thái

Hộp đánh dấu có thể ở một trong ba trạng thái:

  • Chưa chọn: Hộp đánh dấu chưa được chọn. Hộp trống.
  • Không xác định: Hộp đánh dấu đang ở trạng thái không xác định. Hộp này chứa một dấu gạch ngang.
  • Đã chọn: Hộp đánh dấu đã được chọn. Hộp này chứa dấu kiểm.

Hình ảnh sau đây minh hoạ 3 trạng thái của hộp đánh dấu.

Ví dụ về thành phần hộp đánh dấu ở mỗi trong 3 trạng thái: chưa chọn, đã chọn và không xác định.
Hình 1. Ba trạng thái của hộp đánh dấu. Chưa chọn, không xác định và đã chọn.

Triển khai

Bạn có thể sử dụng thành phần kết hợp Checkbox để tạo hộp đánh dấu trong ứng dụng. Bạn chỉ cần lưu ý một vài tham số chính:

  • checked: Giá trị boolean ghi nhận liệu hộp đánh dấu là đã đánh dấu hay bỏ đánh dấu.
  • onCheckedChange(): Hàm mà ứng dụng gọi khi người dùng nhấn vào hộp đánh dấu.

Đoạn mã sau đây minh hoạ cách sử dụng thành phần kết hợp 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"
    )
}

Giải thích

Mã này tạo một hộp đánh dấu ban đầu chưa được đánh dấu. Khi người dùng nhấp vào hộp đánh dấu, lambda onCheckedChange sẽ cập nhật trạng thái checked.

Kết quả

Ví dụ này tạo ra thành phần sau đây khi bỏ đánh dấu:

Hộp đánh dấu chưa được chọn có nhãn. Văn bản bên dưới có nội dung "Checkbox is unchecked" (Hộp đánh dấu chưa được đánh dấu)
Hình 2. Chưa đánh dấu hộp đánh dấu

Và đây là cách hộp đánh dấu tương tự xuất hiện khi được đánh dấu:

Hộp đánh dấu đã chọn có nhãn. Văn bản bên dưới có nội dung "Hộp đánh dấu đã được đánh dấu"
Hình 3. Hộp đánh dấu đã chọn

Ví dụ nâng cao

Sau đây là một ví dụ phức tạp hơn về cách bạn có thể triển khai hộp đánh dấu trong ứng dụng của mình. Trong đoạn mã này, có một hộp đánh dấu mẹ và một loạt hộp đánh dấu con. Khi người dùng nhấn vào hộp đánh dấu mẹ, ứng dụng sẽ đánh dấu tất cả hộp đánh dấu con.

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

Giải thích

Sau đây là một số điểm bạn cần lưu ý từ ví dụ này:

  • Quản lý trạng thái:
    • childCheckedStates: Danh sách các giá trị boolean sử dụng mutableStateOf() để theo dõi trạng thái đã đánh dấu của mỗi hộp đánh dấu con.
    • parentState: ToggleableState có giá trị bắt nguồn từ trạng thái của hộp đánh dấu con.
  • Thành phần giao diện người dùng:
    • TriStateCheckbox: Cần thiết cho hộp đánh dấu mẹ vì hộp đánh dấu này có thông số state cho phép bạn đặt hộp đánh dấu này thành không xác định.
    • Checkbox: Dùng cho mỗi hộp đánh dấu con có trạng thái được liên kết với phần tử tương ứng trong childCheckedStates.
    • Text: Hiển thị nhãn và thông báo ("Chọn tất cả", "Tuỳ chọn X", "Tất cả tuỳ chọn đã được chọn").
  • Logic:
    • onClick của hộp đánh dấu mẹ sẽ cập nhật tất cả các hộp đánh dấu con thành trái ngược với trạng thái mẹ hiện tại.
    • onCheckedChange của mỗi hộp đánh dấu con sẽ cập nhật trạng thái tương ứng trong danh sách childCheckedStates.
    • Mã này sẽ hiển thị "All options selected" khi tất cả các hộp đánh dấu con được đánh dấu.

Kết quả

Ví dụ này tạo ra thành phần sau khi tất cả các hộp đánh dấu đều không được đánh dấu.

Một loạt các hộp đánh dấu đã bỏ đánh dấu và có nhãn đi kèm.
Hình 4. Hộp đánh dấu chưa được chọn

Tương tự, đây là cách thành phần xuất hiện khi tất cả các tuỳ chọn đều được đánh dấu, như khi người dùng nhấn vào chọn tất cả:

Một loạt hộp đánh dấu có nhãn được đánh dấu. Mục đầu tiên được đánh dấu là "chọn tất cả". Có một thành phần văn bản bên dưới các tuỳ chọn này, có nội dung "all options selected" (tất cả các tuỳ chọn đã được chọn).
Hình 5. Đã đánh dấu vào hộp

Khi chỉ một tuỳ chọn được chọn, hộp đánh dấu mẹ sẽ hiển thị trạng thái không xác định:

Một loạt hộp đánh dấu chưa được chọn có nhãn. Tất cả đều không được đánh dấu, ngoại trừ một mục. Hộp đánh dấu có nhãn "chọn tất cả" là không xác định và hiển thị dấu gạch ngang.
Hình 6. Hộp đánh dấu không xác định

Tài nguyên khác