8

TL;DR - What is the correct way to programatically select a default choice Chip that is a child of a ChipGroup in Android?

--

In my android app, I am using com.google.android.material.chip.Chip styled as @style/Widget.MaterialComponents.Chip.Choice components to represent choices of activities a user can select for a given route (think walk, bike, etc)

Because a route can have different types of activities, I insert each type as a different chip programatically into a com.google.android.material.chip.ChipGroup. I also select the default chip as being the first one inserted in the list using the following code during onViewCreated() of my fragment

 private fun setupTypeSelection(types: List<Type>) {
    types.forEach { type ->
        val chip = layoutInflater.inflate(R.layout.chip_type, viewBinding.typeChipGroup, false) as Chip

        chip.tag = type
        /* Init chip text and icon */

        chip.setOnClickListener {
            /* Update selected type */
        }

        if (currentType == null) {
            chip.isSelected = true
            currentType = type
        }

        viewBinding.typeChipGroup.addView(chip)
    }
}

Here's the layout definition of the ChipGroup, where a I set single selection, etc

chip_group_layout.xml

<com.google.android.material.chip.ChipGroup
      android:id="@+id/type_container"

      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginTop="@dimen/margin_medium"

      app:chipSpacingHorizontal="@dimen/margin_medium"
      app:selectionRequired="true"
      app:singleLine="true"
      app:singleSelection="true" />

And here is the chip layout

chip_type.xml

<com.google.android.material.chip.Chip xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
     xmlns:app="http://schemas.android.com/apk/res-auto"

     style="@style/Widget.MaterialComponents.Chip.Choice"

     android:layout_width="wrap_content"
     android:layout_height="wrap_content"

     app:chipIconEnabled="true" />

The problem I'm facing is that the chip that was set programatically as selected chip.isSelected = true stays selected even after the user selects a different one through UI interaction.

What is the correct way to programatically select a default choice Chip that is a child of a ChipGroup in Android?

Lorenzo Petroli
  • 458
  • 6
  • 14

3 Answers3

10

Found my answer.

  • Use View.generateViewId() and assign the new Id to the newly create chip. Then, add
  • Add chip to its parent ChipGroup
  • Check chip view ChipGroup using viewBinding.typeChipGroup.check(id)

This is the final code:

private fun setupTypeSelection(types: List<Trail.Type>) {

    types.forEach { type ->
        val chip = layoutInflater.inflate(R.layout.chip_trail_type, viewBinding.typeContainer, false) as Chip

        chip.id = View.generateViewId()
        /* Set chip details as usual */

        viewBinding.typeContainer.addView(chip)

        if (currentType == null) viewBinding.typeChipGroup.check(chip.id)
    }
}
Lorenzo Petroli
  • 458
  • 6
  • 14
0

currentType == null condition will be false for next selection. Are you making it null anywhere else?

Use ChipGroup's setOnCheckedChangeListener to check the state of chip selection instead of chip.setOnClickListener

Vel
  • 74
  • 4
0
val chipGroup = findViewById<ChipGroup>(R.id.chip_group)
val tileSize320 = findViewById<Chip>(R.id.tile_size320)
chipGroup.check(tileSize320)
  • While this code may solve the question, [including an explanation](//meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. – Adrian Mole Sep 17 '22 at 21:52