Кнопка Еще в ChipGroup

Необходимо сделать "облако тегов", думаю делать через ChipGroup. Еще нужно чтобы можно было сворачивать ChipGroup до двух строк.

Например, если в ChipGroup очень много Chip элементов то нужно сделать так чтобы можно было свернуть до двух рядов и последний chip назвать "Еще" при нажатии все Chip`ы отображаются..

Как это можно сделать?

<com.google.android.material.chip.ChipGroup
    android:id="@+id/chipGroup"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

  <!-- Chips can be declared here, or added dynamically. -->

</com.google.android.material.chip.ChipGroup>

p.s. Если я правильно понял, кто-то уже внес pull request с такой фичей в репозиторий. Разбираюсь, но не совсем то что нужно..

Должно получится так

введите сюда описание изображения


Ответы (1 шт):

Автор решения: Tiarait

Сделал как и описывал ранее - отталкивался от готового ChipGroup. Единственный минус это отсутствие анимации какой либо. Я уже сильно привык DiffCallback. Результат выложил на Гит. Возможно кто сможет подружить FlowLayout и некое подобие DiffCallback'а тогда это будет идеально решение. (Или напишет свою оболочку)


Добавляем библиотеку

implementation 'com.google.android.material:material:1.2.0'

Ваша тема должна наследоваться от Theme.MaterialComponents

Задекларируем стиль с новыми переменными

<declare-styleable name="ChipGroup">
        <attr name="maxRow" format="reference|integer"/>
        <attr name="additionalChipMore" format="reference|string"/>
        <attr name="additionalChipHide" format="reference|string"/>
        <attr name="additionalChipColor" format="reference|color"/>
        <attr name="additionalChipColorPressed" format="reference|color"/>
        <attr name="additionalTextColor" format="reference|color"/>
        <attr format="dimension" name="lineSpacing"/>
        <attr format="dimension" name="itemSpacing"/>
    </declare-styleable>

Дальше отдельно выложил файл на гите ExtendedChipGroup.kt, тут попытаюсь объяснить вкратце. Для начала в конструкторе достаем все переменные из стилей, по сколько некоторые переменные нам нельзя вытянуть, хотя мы и наследуемся от ChipGroup, то придется местами продублировать код. Или же добавить в билд

lintOptions {
    disable 'RestrictedApi'
}

Я пошел по первому пути. Далее переписываем функцию onLayout и там где идет подсчет строк, а именно в цикле где rowCount++ добавляется кусок кода

//если строк больше чем maxRow - заменяем последний элемент пред строки на
//"chipMoreTitle/ЕЩЕ (колво оставшихся)"
if (row > maxRow && (i - 1) > 0  && chipMoreTitle.isNotEmpty()) {
                getChildAt(i).visibility = View.GONE
                val showChip = (getChildAt(i - 1) as Chip)
                showChip.chipBackgroundColor = colorStateList
                showChip.setTextColor(chipMoreColorText)
                showChip.text = chipMoreTitle + " (${childCount - i + 1})"
                showChip.isCheckable = false
                showChip.isSelected = false
                //при клике на chipMoreTitle выставляем maxRow на максимум и обновляем элементы
                //после добавляем chipHideTitle
                showChip.setOnClickListener {
                    maxRow = Int.MAX_VALUE
                    setChips(ArrayList(lastChipsList))

                    if (chipHideTitle.isNotEmpty()) {
                        val hideChip = Chip(context)
                        hideChip.chipBackgroundColor = colorStateList
                        hideChip.setTextColor(chipMoreColorText)
                        hideChip.text = chipHideTitle
                        hideChip.isSelected = false
                        hideChip.isCheckable = false
                        //при клике на chipHideTitle выставляем maxRow на заданный и обновляем элементы
                        hideChip.setOnClickListener {
                            maxRow = maxRowDef
                            setChips(ArrayList(lastChipsList))
                        }
                        addView(hideChip)
                    }
                }
            }

В layout'е прописываем наш новый ChipGroup

<io.github.tiarait.extendedchipgroup.ExtendedChipGroup
                android:id="@+id/chip_group"
                app:maxRow="2"
                app:itemSpacing="6dp"
                app:additionalTextColor="#eee"
                app:additionalChipColor="@color/colorDarkBtn"
                app:additionalChipColorPressed="@color/colorDarkBtnSecondary"
                app:additionalChipMore="@string/btn_show"
                app:additionalChipHide="@string/btn_hide"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>

где

maxRow (int) - максимальное количество строк ChipGroup
additionalTextColor (color) - цвет текста дополнительных кнопок
additionalChipColor (color) - цвет фона для доп кнопок (состояние покоя)
additionalChipColorPressed (color) - цвет фона для доп кнопок (при нажатии)
additionalChipMore (string) - заголовок для кнопки ЕЩЕ
additionalChipHide (string) - заголовок для кнопки скрытия

введите сюда описание изображения

→ Ссылка