How to Implement Checkbox in Jetpack Compose?

Jetpack Compose Checkbox

In this article, we will learn how to implement Checkbox and TriStateCheckbox APIs in Jetpack Compose.

Prerequisites:

What is Checkbox in Android Jetpack Compose?

A checkbox helps the user to select an item. Checkboxes can turn an option on or off.

Example:

Jetpack Compose Checkbox with text or label

For this article, open MainActivity, create a MyUI() composable and call it from the onCreate() method.

import android.content.Context
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.state.ToggleableState
import androidx.compose.ui.unit.dp
import androidx.compose.ui.graphics.Color

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            YourProjectNameTheme(darkTheme = false) {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    Column(
                        modifier = Modifier
                            .fillMaxSize(),
                        verticalArrangement = Arrangement.Center,
                        horizontalAlignment = Alignment.CenterHorizontally
                    ) {
                        MyUI()
                    }
                }
            }
        }
    }
}

@Composable
private fun MyUI() {

}

We will write our code in the MyUI().

Jetpack Compose provides Checkbox API. It looks like this:

@Composable
fun Checkbox(
    checked: Boolean,
    onCheckedChange: ((Boolean) -> Unit)?,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    colors: CheckboxColors = CheckboxDefaults.colors()
)

checked – If the checkbox is checked or not.

onCheckedChange – A lambda that is called when the checkbox is clicked. It contains a boolean value that shows if the component is checked or not.

modifier – To modify the layout of the checkbox.

enabled – If the user can interact with the checkbox. If it is false, the component is grayed out.

interactionSource – We can observe and customize the interactions. For example, we can disable the ripple effect.

colors – We can customize the checkbox colors (like checked and unchecked colors).

Simple Checkbox example:

For the proper functioning of the checkbox, checked and onCheckedChange parameters are mandatory.

@Composable
private fun MyUI() {

    val contextForToast = LocalContext.current.applicationContext

    var checked by remember {
        mutableStateOf(true)
    }

    Checkbox(
        checked = checked,
        onCheckedChange = { checked_ ->
            checked = checked_
            Toast.makeText(contextForToast, "checked_ = $checked_", Toast.LENGTH_SHORT).show()
        }
    )
}

Output:

Simple Checkbox example

Checkbox with Text/Label:

There is no parameter to add text to the checkbox. We can put the Text() and Checkbox() composables in a Row layout.

@Composable
private fun MyUI() {

    val contextForToast = LocalContext.current.applicationContext

    var checked by remember {
        mutableStateOf(true)
    }

    Row(verticalAlignment = Alignment.CenterVertically) {
        Checkbox(
            checked = checked,
            onCheckedChange = { checked_ ->
                checked = checked_
                Toast.makeText(contextForToast, "checked_ = $checked_", Toast.LENGTH_SHORT).show()
            }
        )

        Text(
            modifier = Modifier.padding(start = 2.dp),
            text = "Cheese"
        )
    }
}

Output:

Checkbox with text or label

Checkbox Colors:

CheckboxDefaults.colors() method helps us to change the checkbox colors.

@Composable
public final fun colors(
    checkedColor: Color,
    uncheckedColor: Color,
    checkmarkColor: Color,
    disabledColor: Color,
    disabledIndeterminateColor: Color
): CheckboxColors

Example:

@Composable
private fun MyUI() {

    val contextForToast = LocalContext.current.applicationContext

    var checked by remember {
        mutableStateOf(true)
    }

    Row(verticalAlignment = Alignment.CenterVertically) {
        Checkbox(
            checked = checked,
            onCheckedChange = { checked_ ->
                checked = checked_
                Toast.makeText(contextForToast, "checked_ = $checked_", Toast.LENGTH_SHORT).show()
            },
            colors = CheckboxDefaults.colors(
                checkedColor = Color.Green
            )
        )

        Text(
            modifier = Modifier.padding(start = 2.dp),
            text = "Cheese"
        )
    }
}

Output:

Checkbox colors

Related: Colors, Fonts, and Shapes in Jetpack Compose

Checkbox Size:

To change the checkbox size, use the Modifier‘s scale() method.

@Composable
private fun MyUI() {

    val contextForToast = LocalContext.current.applicationContext

    var checked by remember {
        mutableStateOf(true)
    }

    Row(verticalAlignment = Alignment.CenterVertically) {
        Checkbox(
            modifier = Modifier.scale(scale = 1.6f),
            checked = checked,
            onCheckedChange = { checked_ ->
                checked = checked_
                Toast.makeText(contextForToast, "checked_ = $checked_", Toast.LENGTH_SHORT).show()
            }
        )

        Text(
            modifier = Modifier.padding(start = 2.dp),
            text = "Cheese"
        )
    }
}

Output:

Checkbox Size

List of Checkboxes:

If you have a list of checkboxes, create them using the Checkbox() composable and place them inside a Column layout.

private val fruitsList: List<String> = listOf("Apple", "Mangoes", "Melons")

@Composable
private fun MyUI() {

    val contextForToast = LocalContext.current.applicationContext

    Column(horizontalAlignment = Alignment.Start) {

        fruitsList.forEach { fruitName ->

            var checked by remember {
                mutableStateOf(true)
            }

            Row(verticalAlignment = Alignment.CenterVertically) {
                Checkbox(
                    checked = checked,
                    onCheckedChange = { checked_ ->
                        checked = checked_
                        Toast.makeText(contextForToast, "$fruitName $checked_", Toast.LENGTH_SHORT)
                            .show()
                    }
                )

                Text(
                    modifier = Modifier.padding(start = 2.dp),
                    text = fruitName
                )
            }
        }
    }
}

Output:

List of Checkboxes

Tri-state Checkbox in Jetpack Compose:

There is another checkbox with 3 states. It is called the TriStateCheckbox.

Example:

tri state checkbox

In the above image, “Operating Systems” is the tri-state checkbox, and Ubuntu, Windows, and Mac are its children (normal checkboxes).

Let’s look at the 3 states:

ToggleableState.On – In this state, all the children are checked.
ToggleableState.Off – All the children are unchecked.
ToggleableState.Indeterminate – If some, but not all, child checkboxes are checked.

Example:

@Composable
private fun MyUI() {

    // child checkbox states
    var checkBox1State by remember {
        mutableStateOf(true)
    }
    var checkBox2State by remember {
        mutableStateOf(true)
    }
    var checkBox3State by remember {
        mutableStateOf(true)
    }

    // parent (tri-state) checkbox state
    // it is changed whenever its children's state is changed
    val parentCheckBoxState = remember(checkBox1State, checkBox2State, checkBox3State) {
        if (checkBox1State && checkBox2State && checkBox3State) ToggleableState.On // if all the children are checked
        else if (!checkBox1State && !checkBox2State && !checkBox3State) ToggleableState.Off // if all the children are unchecked
        else ToggleableState.Indeterminate // some of the children are checked, others unchecked
    }

    Column(horizontalAlignment = Alignment.Start) {
        Row(verticalAlignment = Alignment.CenterVertically) {
            // parent checkbox
            TriStateCheckbox(
                state = parentCheckBoxState,
                onClick = {
                    // click event on the parent checkbox.
                    // if the parent checkbox is checked (ToggleableState.On), make all the children unchecked
                    // else, make them checked
                    val state = !(parentCheckBoxState == ToggleableState.On)
                    checkBox1State = state
                    checkBox2State = state
                    checkBox3State = state
                }
            )
            Text(
                modifier = Modifier.padding(start = 2.dp),
                text = "Operating Systems"
            )
        }

         // child checkboxes
        CheckBoxItem(
            checked = checkBox1State,
            osName = "Ubuntu",
            onCheckedChange = { checkBox1State = it }
        )
        CheckBoxItem(
            checked = checkBox2State,
            osName = "Windows",
            onCheckedChange = { checkBox2State = it }
        )
        CheckBoxItem(
            checked = checkBox3State,
            osName = "Mac",
            onCheckedChange = { checkBox3State = it }
        )
    }
}

@Composable
private fun CheckBoxItem(
    checked: Boolean,
    osName: String,
    contextForToast: Context = LocalContext.current.applicationContext,
    onCheckedChange: (Boolean) -> Unit,
) {
    Row(
        modifier = Modifier.padding(start = 12.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Checkbox(
            checked = checked,
            onCheckedChange = { checked_ ->
                onCheckedChange(checked_)
                Toast.makeText(contextForToast, "$osName $checked_", Toast.LENGTH_SHORT)
                    .show()
            }
        )

        Text(
            modifier = Modifier.padding(start = 2.dp),
            text = osName
        )
    }
}

Output:

jetpack compose tri state checkbox

This is all about checkbox APIs in Android Jetpack Compose. I hope you have learned something new. If you have any doubts, comment below.

Related Articles:

References:

Leave a Comment