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