ChipGroup single selection
To prevent all chips from being deselected you can use the method setSelectionRequired
:
chipGroup.setSelectionRequired(true)
You can also define it in the layout using the app:selectionRequired
attribute:
<com.google.android.material.chip.ChipGroup app:singleSelection="true" app:selectionRequired="true" app:checkedChip="@id/..." ..>
Note: This requires a minimum of version 1.2.0
EDIT
With version 1.2.0-alpha02
the old hacky solution is no longer required!
Either use the attribute app:selectionRequired="true"
<com.google.android.material.chip.ChipGroup android:id="@+id/group" android:layout_width="match_parent" android:layout_height="wrap_content" app:selectionRequired="true" app:singleSelection="true"> (...)</com.google.android.material.chip.ChipGroup>
Or in code
// Kotlingroup.isSelectionRequired = true// Javagroup.setSelectionRequired(true);
For older versions 👇
There are two steps to achieve this
Step 1
We have this support built-in, just make sure to add app:singleSelection="true"
to your ChipGroup
, for example:
XML
<com.google.android.material.chip.ChipGroup android:id="@+id/group" android:layout_width="match_parent" android:layout_height="wrap_content" app:singleSelection="true"> <com.google.android.material.chip.Chip android:id="@+id/option_1" style="@style/Widget.MaterialComponents.Chip.Choice" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Option 1" /> <com.google.android.material.chip.Chip android:id="@+id/option_2" style="@style/Widget.MaterialComponents.Chip.Choice" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Option 2" /></com.google.android.material.chip.ChipGroup>
Code
// Kotlingroup.isSingleSelection = true// Javagroup.setSingleSelection(true);
Step 2
Now to support a radio group like functionality:
var lastCheckedId = View.NO_IDchipGroup.setOnCheckedChangeListener { group, checkedId -> if(checkedId == View.NO_ID) { // User tried to uncheck, make sure to keep the chip checked group.check(lastCheckedId) return@setOnCheckedChangeListener } lastCheckedId = checkedId // New selection happened, do your logic here. (...)}
From the docs:
ChipGroup also supports a multiple-exclusion scope for a set of chips. When you set the app:singleSelection attribute, checking one chip that belongs to a chip group unchecks any previously checked chip within the same group. The behavior mirrors that of RadioGroup.
A solution would be to preset a clicked chip and then toggling the clickable property of the chips:
chipGroup.setOnCheckedChangeListener((chipGroup, id) -> { Chip chip = ((Chip) chipGroup.getChildAt(chipGroup.getCheckedChipId())); if (chip != null) { for (int i = 0; i < chipGroup.getChildCount(); ++i) { chipGroup.getChildAt(i).setClickable(true); } chip.setClickable(false); }});