ChipGroup одиночный выбор - PullRequest
       46

ChipGroup одиночный выбор

0 голосов
/ 05 ноября 2018

Как я могу заставить ChipGroup вести себя как RadioGroup как при наличии хотя бы одного выбранного элемента всегда? Настройка setSingleSelection(true) также добавляет возможность выбора ничего, если вы дважды щелкнете на Chip.

Ответы [ 5 ]

0 голосов
/ 08 июля 2019

Для достижения этой цели есть два шага

Шаг 1

У нас есть встроенная поддержка, просто добавьте app:singleSelection="true" к вашему ChipGroup, например:

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>

Код


// Kotlin
group.isSingleSelection = true

// Java
group.setSingleSelection(true);

Шаг 2

Теперь для поддержки группы радиосвязи, например:


var lastCheckedId = View.NO_ID
chipGroup.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.
    (...)

}

Из документов :

ChipGroup также поддерживает область множественного исключения для набора микросхем. Когда вы устанавливаете атрибут app: singleSelection, проверяете один чип, который принадлежит к группе чипов, снимает флажок с любого ранее проверенного чипа в та же группа. Поведение отражает поведение RadioGroup.

0 голосов
/ 04 февраля 2019

Большинство ответов великолепны и действительно полезны для меня. Еще одно небольшое изменение в @adriennoir и @Todd DeLand, чтобы предотвратить снятие отметки с уже проверенного чипа в setSingleSelection(true) ChipGroup, вот мое решение:

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
}

Для меня мне просто нужно, чтобы тот же проверенный чип не был снят, чтобы он не был кликабельным. Таким образом, пользователь все еще может щелкнуть по проверенному чипу и увидеть причудливый эффект ряби, и ничего не произойдет.

0 голосов
/ 19 января 2019

Краткое изменение ответа @adriennoir (на Kotlin). Спасибо за помощь! Обратите внимание, что getChildAt() принимает индекс.

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

Вот мой большой `setOnCheckedChangeListener, для контекста:

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)
        }
    }

}
0 голосов
/ 24 января 2019

Вот как я это сделал:

var previousSelection: Int = default_selection_id 
chipGroup.setOnCheckedChangeListener { chipGroup, id ->
    if (id == -1) //nothing is selected.
        chipGroup.check(previousSelection)
    else
        previousSelection = id
0 голосов
/ 05 ноября 2018

Решение состоит в том, чтобы предварительно установить чип, по которому щелкают, а затем переключить свойство фишек, по которому можно нажимать:

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);
    }
});
...