web-dev-qa-db-fra.com

ChipGroup sélection unique

Comment puis-je forcer une ChipGroup à agir comme une RadioGroup en ayant toujours au moins un élément sélectionné? La définition de setSingleSelection(true) ajoute également la possibilité de ne rien sélectionner si vous cliquez deux fois sur une Chip.

5
adriennoir

Une solution serait de prédéfinir une puce cliquée puis de basculer la propriété cliquable des puces:

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);
    }
});
5
adriennoir

Brève modification de la réponse de @adriennoir (en kotlin). Merci pour l'aide! Notez que getChildAt() prend un index.

for (i in 0 until group.childCount) {
    val chip = group.getChildAt(i)
    chip.isClickable = chip.id != group.checkedChipId
}

Voici mon plus grand `setOnCheckedChangeListener, pour le contexte:

intervalChipGroup.setOnCheckedChangeListener { group, checkedId ->

    for (i in 0 until group.childCount) {
        val chip = group.getChildAt(i)
        chip.isClickable = chip.id != group.checkedChipId
    }

    when (checkedId) {
        R.id.intervalWeek -> {
            view.findViewById<Chip>(R.id.intervalWeek).chipStrokeWidth = 1F
            view.findViewById<Chip>(R.id.intervalMonth).chipStrokeWidth = 0F
            view.findViewById<Chip>(R.id.intervalYear).chipStrokeWidth = 0F
            currentIntervalSelected = weekInterval
            populateGraph(weekInterval)
        }
        R.id.intervalMonth -> {
            view.findViewById<Chip>(R.id.intervalWeek).chipStrokeWidth = 0F
            view.findViewById<Chip>(R.id.intervalMonth).chipStrokeWidth = 1F
            view.findViewById<Chip>(R.id.intervalYear).chipStrokeWidth = 0F
            currentIntervalSelected = monthInterval
            populateGraph(monthInterval)

        }
        R.id.intervalYear -> {
            view.findViewById<Chip>(R.id.intervalWeek).chipStrokeWidth = 0F
            view.findViewById<Chip>(R.id.intervalMonth).chipStrokeWidth = 0F
            view.findViewById<Chip>(R.id.intervalYear).chipStrokeWidth = 1F
            currentIntervalSelected = yearInterval
            populateGraph(yearInterval)
        }
    }

}
3
Todd DeLand

La plupart des réponses sont excellentes et vraiment utiles pour moi. Une autre légère modification à @adriennoir et @Todd DeLand, pour éviter de décocher la puce déjà vérifiée dans un groupe de fonctions setSingleSelection(true), voici ma solution:

for (i in 0 until chipGroup.childCount) {
    val chip = chipGroup.getChildAt(i) as Chip
    chip.isCheckable = chip.id != chipGroup.checkedChipId
    chip.isChecked = chip.id == chipGroup.checkedChipId
}

Pour moi, je dois juste éviter que la même puce cochée ne soit décochée sans la rendre non cliquable. De cette façon, l'utilisateur peut toujours cliquer sur la puce vérifiée et voir l'effet d'entraînement fantaisie et rien ne se passera.

0
toktorio

Voici comment je l'ai fait:

var previousSelection: Int = default_selection_id 
chipGroup.setOnCheckedChangeListener { chipGroup, id ->
    if (id == -1) //nothing is selected.
        chipGroup.check(previousSelection)
    else
        previousSelection = id
0
UpsideDownTree