Checkbox

Checkboxes let users select one or more items from a list. You might use a checkbox to let the user do the following:

  • Turn an item on or off.
  • Select from multiple options in a list.
  • Indicate agreement or acceptance.

Anatomy

A checkbox consists of the following elements:

  • Box: This is the container for the checkbox.
  • Check: This is the visual indicator that shows whether the checkbox is selected or not.
  • Label: This is the text that describes the checkbox.

States

A checkbox can be in one of three states:

  • Unselected: The checkbox is not selected. The box is empty.
  • Indeterminate: The checkbox is in an indeterminate state. The box contains a dash.
  • Selected: The checkbox is selected. The box contains a checkmark.

The following image demonstrates the three states of a checkbox.

An example of a checkbox component in each of its three states: unselected, selected, and indeterminate.
Figure 1. The three states of a checkbox. Unselected, indeterminate, and selected.

Implementation

You can use the Checkbox composable to create a checkbox in your app. There are just a few key parameters to keep in mind:

  • checked: The boolean that captures whether the checkbox is checked or unchecked.
  • onCheckedChange(): The function that the app calls when the user taps the checkbox.

The following snippet demonstrates how to use the Checkbox composable:

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

Explanation

This code creates a checkbox that is initially unchecked. When the user clicks on the checkbox, the onCheckedChange lambda updates the checked state.

Result

This example produces the following component when unchecked:

An unchecked checkbox with a label. The text beneath it reads 'Checkbox is unchecked'
Figure 2. Unchecked checkbox

And this is how the same checkbox appears when checked:

A checked checkbox with a label. The text beneath it reads 'Checkbox is checked'
Figure 3. Checked checkbox

Advanced example

The following is a more complex example of how you can implement checkboxes in your app. In this snippet, there is a parent checkbox and a series of child checkboxes. When the user taps the parent checkbox, the app checks all child checkboxes.

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

Explanation

The following are several points you should note from this example:

  • State management:
    • childCheckedStates: A list of booleans using mutableStateOf() to track the checked state of each child checkbox.
    • parentState: A ToggleableState whose value derives from the child checkboxes' states.
  • UI components:
    • TriStateCheckbox: Is necessary for the parent checkbox as it has a state param that lets you set it to indeterminate.
    • Checkbox: Used for each child checkbox with its state linked to the corresponding element in childCheckedStates.
    • Text: Displays labels and messages ("Select all", "Option X", "All options selected").
  • Logic:
    • The parent checkbox's onClick updates all child checkboxes to the opposite of the current parent state.
    • Each child checkbox's onCheckedChange updates its corresponding state in the childCheckedStates list.
    • The code displays "All options selected" when all child checkboxes are checked.

Result

This example produces the following component when all checkboxes are unchecked.

A series of unchecked labeled checkboxes with a label.
Figure 4. Unchecked checkboxes

Likewise, this is how the component appears when all options are checked, as when the user taps select all:

A series of checked labeled checkboxes checkbox with a label. The first is marked 'select all'. There is a text component beneath them that reads 'all options selected.'
Figure 5. Checked checkboxes

When only one option is checked the parent checkbox display the indeterminate state:

A series of unchecked labeled checkboxes checkbox with a label. All but one is unchecked. The checkbox labeled 'select all' is indeterminate, displaying a dash.
Figure 6. Indeterminate checkbox

Additional resources

Content and code samples on this page are subject to the licenses described in the Content License. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.

Last updated 2026-03-30 UTC.