Checkbox parent child relationship android

Viewed 926

I want to create a parent-child relationship for Checkbox in Android as per the material design guidelines given in https://material.io/components/selection-controls#checkboxes.

I want a parent Checkbox under which there will be child checkboxes and When the parent checkbox is checked, all child checkboxes are checked.

If a parent checkbox is unchecked, all child checkboxes are unchecked.

If some, but not all, child checkboxes are checked, the parent checkbox becomes an indeterminate checkbox.

I checked developer docs https://developer.android.com/guide/topics/ui/controls/checkbox but there is no information about this.

Also, I checked material design docs https://material.io/develop/android/components/checkbox/, they have given the guideline to do the same, however, they haven't given any example project to do the same.

I tried creating a Parent-Child relationship with the checkbox using nesting but that didn't work. Does anyone have an idea about how to implement this?

1 Answers

You will need to set up a listener on your 'parent' CheckBox, to toggle the 'child' CheckBoxes when the state of your 'parent' CheckBox changes.

See here to set-up the listener: https://developer.android.com/reference/android/widget/CompoundButton#setOnCheckedChangeListener(android.widget.CompoundButton.OnCheckedChangeListener)

Here's an example:

    val childCheckBoxes = listOf(checkBox1, checkBox2, checkBox3)
    parentCheckBox.setOnCheckedChangeListener { _, isChecked ->
        childCheckBoxes.forEach {
            it.isChecked = isChecked
        }
    }

At the same time, it sounds like you need to add listeners to each child CheckBox, to update the parent CheckBox state - such that if any of the child CheckBoxes are checked, the parent is also checked. Bear in mind that if you call parentCheckBox.isChecked = true it will also call the OnCheckedChangeListener of parentCheckBox, and you'll end up with infinite recursion. So you'll probably want to disable the OnCheckedChangeListener when setting isChecked like this. That could look like this:

val theRealListener = { _, isChecked ->
        childCheckBoxes.forEach {
            it.isChecked = isChecked
        }
    }
parentCheckBox.setOnCheckedChangeListener(null)
parentCheckBox.isChecked = whatever
parentCheckBox.setOnCheckedChangeListener(theRealListener)

The 'indeterminate' state is not included in the default Android CheckBox - it can only be 'checked' or 'unchecked'. You will need to use something custom for this. Perhaps this library will be useful to you: https://github.com/sevar83/indeterminate-checkbox

If you decide to use this library, it looks like you will need to use setOnStateChangedListener rather than setOnCheckedChangeListener, but the idea stays the same.

Related