Merge branch 'tag_filters' into range_filter

# Conflicts:
#	base-filters/README.md
This commit is contained in:
Anastasiya97 2022-08-29 21:31:46 +03:00
commit 853d32236a
12 changed files with 205 additions and 203 deletions

View File

@ -13,16 +13,18 @@
### Как использовать ### Как использовать
``` kotlin ``` kotlin
val selectorView = ListSelectionView<DefaultSelectionItem, SelectionItemViewHolder<DefaultSelectionItem>>(context) val selectorView = ListSelectionView<DefaultSelectionItem, SelectionItemViewHolder<DefaultSelectionItem>>(context)
.setItems(navArgs.items) .Builder()
.addItemDecoration((TopDividerItemDecoration( .setItems(navArgs.items)
context = requireContext(), .addItemDecoration((TopDividerItemDecoration(
drawableId = R.drawable.list_divider_1dp, context = requireContext(),
startMargin = START_MARGIN_DIVIDER_DP.px drawableId = R.drawable.list_divider_1dp,
))) startMargin = START_MARGIN_DIVIDER_DP.px
.withSelectionType(ListSelectionView.SelectionType.SINGLE_SELECT) )))
.onResultListener { items -> .withSelectionType(ListSelectionView.SelectionType.SINGLE_SELECT)
viewModel.dispatchAction(SelectItemAction.SelectItem(items)) } .onResultListener { items ->
.build() viewModel.dispatchAction(SelectItemAction.SelectItem(items))
}
.build()
``` ```
### Конфигурации ### Конфигурации
* при создании `ListSelectionView<ItemType, HolderType>` необходимо передлать `ItemType` - класс модели данных в списке, `HolderType` - класс viewHolder-а в recyclerView. * при создании `ListSelectionView<ItemType, HolderType>` необходимо передлать `ItemType` - класс модели данных в списке, `HolderType` - класс viewHolder-а в recyclerView.
@ -35,15 +37,16 @@ val selectorView = ListSelectionView<DefaultSelectionItem, SelectionItemViewHold
* метод `showInHolder(HolderFactoryType<ItemType>)` используется для определения кастомного viewHolder для списка с недефолтной разметкой. * метод `showInHolder(HolderFactoryType<ItemType>)` используется для определения кастомного viewHolder для списка с недефолтной разметкой.
``` kotlin ``` kotlin
val selectorView = ListSelectionView<TestSelectionItem, TestItemViewHolder>(context) val selectorView = ListSelectionView<TestSelectionItem, TestItemViewHolder>(context)
.showInHolder { parent, clickListener, selectionType -> .Builder()
TestItemViewHolder( .showInHolder { parent, clickListener, selectionType ->
binding = TestSelectionItemBinding.inflate(LayoutInflater.from(parent.context), parent, false), TestItemViewHolder(
onItemSelectAction = clickListener, binding = TestSelectionItemBinding.inflate(LayoutInflater.from(parent.context), parent, false),
selectionType = selectionType onItemSelectAction = clickListener,
) selectionType = selectionType
} )
... }
.build() ...
.build()
``` ```
* колбэк `onSelectedItemsListener(listener: OnSelectedItemsListener<ItemType>)` можно использовать для получения списка всех элементов `ItemType` после каждого выбора * колбэк `onSelectedItemsListener(listener: OnSelectedItemsListener<ItemType>)` можно использовать для получения списка всех элементов `ItemType` после каждого выбора
* колбэк `onSelectedItemListener(listener: OnSelectedItemListener<ItemType>)` можно использовать для получения элемента списка `ItemType`, по которому произошел клик * колбэк `onSelectedItemListener(listener: OnSelectedItemListener<ItemType>)` можно использовать для получения элемента списка `ItemType`, по которому произошел клик
@ -80,8 +83,9 @@ val selectorView = ListSelectionView<TestSelectionItem, TestItemViewHolder>(cont
``` kotlin ``` kotlin
val newContext = ContextThemeWrapper(requireContext(), R.style.Theme_Custom_FilterSelection) val newContext = ContextThemeWrapper(requireContext(), R.style.Theme_Custom_FilterSelection)
val selectorView = ListSelectionView(newContext) val selectorView = ListSelectionView(newContext)
... .Builder()
.build() ...
.build()
``` ```
## 2. Выбор одного/нескольких значений из перечня тегов ## 2. Выбор одного/нескольких значений из перечня тегов
@ -92,14 +96,14 @@ val selectorView = ListSelectionView(newContext)
### Как использовать ### Как использовать
``` kotlin ``` kotlin
binding.tagItemLayout binding.tagItemLayout
.setSpacing(16) .Builder(getFilterItem())
.setSelectionType(SelectionType.MULTI_SELECT) // по умолчанию .setSpacing(16)
.isSingleLine(false) // по умолчанию .setSelectionType(SelectionType.MULTI_SELECT) // по умолчанию
.onPropertySelectedAction { filterProperty: FilterProperty -> .isSingleLine(false) // по умолчанию
//Do something .onPropertySelectedAction { filterProperty: FilterProperty ->
} //Do something
.build(getFilterItem())
} }
.build()
``` ```
### Конфигурации ### Конфигурации
* метод `setSelectionType(SelectionType)` конфигурирует тип выбора: * метод `setSelectionType(SelectionType)` конфигурирует тип выбора:
@ -109,9 +113,10 @@ binding.tagItemLayout
* `setTagLayout(Int)` устанавливает разметку для тега. Если не задано - то используется дефолтная разметка `layout_default_tag.xml` * `setTagLayout(Int)` устанавливает разметку для тега. Если не задано - то используется дефолтная разметка `layout_default_tag.xml`
* `setMaxTagCount(Int)` позволяет ограничить количество отображаемых тегов. По умолчанию ограничения нет. * `setMaxTagCount(Int)` позволяет ограничить количество отображаемых тегов. По умолчанию ограничения нет.
* `setMoreTagLayout(Int, String)` устанавливает разметку для тега, который отображается для дополнительного тега. Если не указана - то тег не будет создан * `setMoreTagLayout(Int, String)` устанавливает разметку для тега, который отображается для дополнительного тега. Если не указана - то тег не будет создан
* `setSpacing(Int)`, `setSpacingHorizontal(Int`) и мsetSpacingVertical(Int)` можно использовать для настройки расстояния между тегами. По умолчанию - 0 * `setSpacing(Int)`, `setSpacingHorizontal(Int)` и `setSpacingVertical(Int)` можно использовать для настройки расстояния между тегами. По умолчанию - 0
* `onMoreValuesAction(FilterMoreAction)` и `onPropertySelectedAction(PropertySelectedAction)` используются для передачи колбэков на клик по тегу типа "Еще" и обычного тега соответственно * `onMoreValuesAction(FilterMoreAction)` и `onPropertySelectedAction(PropertySelectedAction)` используются для передачи колбэков на клик по тегу типа "Еще" и обычного тега соответственно
* после вызова конфигурационных методов обязательно необходимо вызать метод `build(FilterItem)` * после вызова конфигурационных методов обязательно необходимо вызать метод `build()`
* в Builder необходимо передать объект `filterItem: FilterItem`
## 3. Выбор минимального и максимального значения из диапозона ## 3. Выбор минимального и максимального значения из диапозона

View File

@ -19,7 +19,11 @@ dependencies {
implementation("androidx.appcompat:appcompat") implementation("androidx.appcompat:appcompat")
implementation("com.google.android.material:material") implementation("com.google.android.material:material")
implementation("androidx.constraintlayout:constraintlayout:2.2.0-alpha03") implementation("androidx.constraintlayout:constraintlayout") {
version {
require '2.0.0'
}
}
constraints { constraints {
implementation("androidx.appcompat:appcompat") { implementation("androidx.appcompat:appcompat") {

View File

@ -14,8 +14,8 @@ import ru.touchin.roboswag.base_filters.select_list_item.adapter.SheetSelectionA
import ru.touchin.roboswag.base_filters.select_list_item.model.BaseSelectionItem import ru.touchin.roboswag.base_filters.select_list_item.model.BaseSelectionItem
import ru.touchin.roboswag.base_filters.SelectionType import ru.touchin.roboswag.base_filters.SelectionType
typealias OnSelectedItemListener<ItemType> = (item: ItemType) -> Unit private typealias OnSelectedItemListener<ItemType> = (item: ItemType) -> Unit
typealias OnSelectedItemsListener<ItemType> = (items: List<ItemType>) -> Unit private typealias OnSelectedItemsListener<ItemType> = (items: List<ItemType>) -> Unit
/** /**
* Base [ListSelectionView] to use in filters screen for choosing single or multi items in list. * Base [ListSelectionView] to use in filters screen for choosing single or multi items in list.
@ -26,7 +26,7 @@ typealias OnSelectedItemsListener<ItemType> = (items: List<ItemType>) -> Unit
* @param HolderType Type of viewHolder in recyclerView. * @param HolderType Type of viewHolder in recyclerView.
* It must implement [BaseSelectionViewHolder] abstract class. * It must implement [BaseSelectionViewHolder] abstract class.
* *
**/ **/
class ListSelectionView<ItemType, HolderType> @JvmOverloads constructor( class ListSelectionView<ItemType, HolderType> @JvmOverloads constructor(
context: Context, context: Context,
@ -34,8 +34,8 @@ class ListSelectionView<ItemType, HolderType> @JvmOverloads constructor(
defStyleAttr: Int = 0, defStyleAttr: Int = 0,
defStyleRes: Int = 0 defStyleRes: Int = 0
) : FrameLayout(context, attrs, defStyleAttr, defStyleRes) ) : FrameLayout(context, attrs, defStyleAttr, defStyleRes)
where ItemType: BaseSelectionItem, where ItemType : BaseSelectionItem,
HolderType: BaseSelectionViewHolder<ItemType>{ HolderType : BaseSelectionViewHolder<ItemType> {
private var mutableItems: List<ItemType> = emptyList() private var mutableItems: List<ItemType> = emptyList()
private var selectionType = SelectionType.SINGLE_SELECT private var selectionType = SelectionType.SINGLE_SELECT
@ -83,37 +83,40 @@ class ListSelectionView<ItemType, HolderType> @JvmOverloads constructor(
updateList() updateList()
} }
fun setItems(items: List<ItemType>) = apply { inner class Builder {
mutableItems = items
}
fun <T> setItems( fun setItems(items: List<ItemType>) = apply {
source: List<T>, mutableItems = items
mapper: (T) -> ItemType }
) = setItems(source.map { item -> mapper.invoke(item) })
fun showInHolder(holderFactory: HolderFactoryType<ItemType>) = apply { fun <T> setItems(
factory = holderFactory source: List<T>,
} mapper: (T) -> ItemType
) = setItems(source.map { item -> mapper.invoke(item) })
fun addItemDecoration(itemDecoration: RecyclerView.ItemDecoration) = apply { fun showInHolder(holderFactory: HolderFactoryType<ItemType>) = apply {
binding.itemsRecycler.addItemDecoration(itemDecoration) factory = holderFactory
} }
fun onSelectedItemListener(listener: OnSelectedItemListener<ItemType>) = apply { fun addItemDecoration(itemDecoration: RecyclerView.ItemDecoration) = apply {
this@ListSelectionView.onSelectedItemChanged = listener binding.itemsRecycler.addItemDecoration(itemDecoration)
} }
fun onSelectedItemsListener(listener: OnSelectedItemsListener<ItemType>) = apply { fun onSelectedItemListener(listener: OnSelectedItemListener<ItemType>) = apply {
this@ListSelectionView.onSelectedItemsChanged = listener this@ListSelectionView.onSelectedItemChanged = listener
} }
fun withSelectionType(type: SelectionType) = apply { fun onSelectedItemsListener(listener: OnSelectedItemsListener<ItemType>) = apply {
selectionType = type this@ListSelectionView.onSelectedItemsChanged = listener
} }
fun build() = apply { fun withSelectionType(type: SelectionType) = apply {
binding.itemsRecycler.adapter = adapter selectionType = type
updateList() }
fun build() = this@ListSelectionView.also {
binding.itemsRecycler.adapter = adapter
updateList()
}
} }
} }

View File

@ -4,7 +4,7 @@ import android.view.View
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import ru.touchin.roboswag.base_filters.select_list_item.model.BaseSelectionItem import ru.touchin.roboswag.base_filters.select_list_item.model.BaseSelectionItem
abstract class BaseSelectionViewHolder<ItemType: BaseSelectionItem>(val view: View) abstract class BaseSelectionViewHolder<ItemType : BaseSelectionItem>(val view: View)
: RecyclerView.ViewHolder(view) { : RecyclerView.ViewHolder(view) {
abstract fun bind(item: ItemType) abstract fun bind(item: ItemType)

View File

@ -5,27 +5,29 @@ import ru.touchin.roboswag.base_filters.databinding.SelectionItemBinding
import ru.touchin.roboswag.base_filters.select_list_item.model.BaseSelectionItem import ru.touchin.roboswag.base_filters.select_list_item.model.BaseSelectionItem
import ru.touchin.roboswag.base_filters.SelectionType import ru.touchin.roboswag.base_filters.SelectionType
class SelectionItemViewHolder<ItemType: BaseSelectionItem>(private val binding: SelectionItemBinding, class SelectionItemViewHolder<ItemType : BaseSelectionItem>(
private val onItemSelectAction: (ItemType) -> Unit, private val binding: SelectionItemBinding,
private val selectionType: SelectionType private val onItemSelectAction: (ItemType) -> Unit,
) : BaseSelectionViewHolder<ItemType>(binding.root) { private val selectionType: SelectionType
) : BaseSelectionViewHolder<ItemType>(binding.root) {
override fun bind(item: ItemType) { override fun bind(item: ItemType) {
binding.run { binding.itemTitle.text = item.title
val checkListener = View.OnClickListener { binding.itemRadiobutton.isChecked = item.isSelected
itemRadiobutton.isChecked = true
onItemSelectAction.invoke(item.copyWithSelection(isSelected = when (selectionType) {
SelectionType.SINGLE_SELECT -> true
else -> !item.isSelected
}))
}
itemTitle.text = item.title setupCheckListener(item)
root.setOnClickListener(checkListener) }
itemRadiobutton.setOnClickListener(checkListener) private fun setupCheckListener(item: ItemType) = with(binding) {
itemRadiobutton.isChecked = item.isSelected val checkListener = View.OnClickListener {
itemRadiobutton.isChecked = true
onItemSelectAction.invoke(item.copyWithSelection(isSelected = when (selectionType) {
SelectionType.SINGLE_SELECT -> true
else -> !item.isSelected
}))
} }
root.setOnClickListener(checkListener)
itemRadiobutton.setOnClickListener(checkListener)
} }
} }

View File

@ -5,11 +5,11 @@ import ru.touchin.roboswag.base_filters.select_list_item.model.BaseSelectionItem
import ru.touchin.roboswag.base_filters.SelectionType import ru.touchin.roboswag.base_filters.SelectionType
import ru.touchin.roboswag.recyclerview_adapters.adapters.DelegationListAdapter import ru.touchin.roboswag.recyclerview_adapters.adapters.DelegationListAdapter
class SheetSelectionAdapter<ItemType: BaseSelectionItem>( class SheetSelectionAdapter<ItemType : BaseSelectionItem>(
onItemSelectAction: (ItemType) -> Unit, onItemSelectAction: (ItemType) -> Unit,
selectionType: SelectionType, selectionType: SelectionType,
factory: HolderFactoryType<ItemType> factory: HolderFactoryType<ItemType>
): DelegationListAdapter<BaseSelectionItem>(object : DiffUtil.ItemCallback<BaseSelectionItem>() { ) : DelegationListAdapter<BaseSelectionItem>(object : DiffUtil.ItemCallback<BaseSelectionItem>() {
override fun areItemsTheSame(oldItem: BaseSelectionItem, newItem: BaseSelectionItem): Boolean = override fun areItemsTheSame(oldItem: BaseSelectionItem, newItem: BaseSelectionItem): Boolean =
oldItem.isItemTheSame(newItem) oldItem.isItemTheSame(newItem)

View File

@ -10,5 +10,5 @@ abstract class BaseSelectionItem(
abstract fun isContentTheSame(compareItem: BaseSelectionItem): Boolean abstract fun isContentTheSame(compareItem: BaseSelectionItem): Boolean
abstract fun <ItemType>copyWithSelection(isSelected: Boolean): ItemType abstract fun <ItemType> copyWithSelection(isSelected: Boolean): ItemType
} }

View File

@ -2,16 +2,13 @@ package ru.touchin.roboswag.base_filters.tags
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View import android.view.View
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.TextView import android.widget.TextView
import androidx.annotation.LayoutRes import androidx.annotation.LayoutRes
import androidx.core.view.isVisible
import com.google.android.material.chip.ChipGroup import com.google.android.material.chip.ChipGroup
import ru.touchin.roboswag.base_filters.R import ru.touchin.roboswag.base_filters.R
import ru.touchin.roboswag.base_filters.SelectionType import ru.touchin.roboswag.base_filters.SelectionType
import ru.touchin.roboswag.base_filters.databinding.TagSelectionLayoutBinding
import ru.touchin.roboswag.base_filters.tags.model.FilterItem import ru.touchin.roboswag.base_filters.tags.model.FilterItem
import ru.touchin.roboswag.base_filters.tags.model.FilterProperty import ru.touchin.roboswag.base_filters.tags.model.FilterProperty
import ru.touchin.roboswag.components.utils.UiUtils import ru.touchin.roboswag.components.utils.UiUtils
@ -27,10 +24,9 @@ class TagLayoutView @JvmOverloads constructor(
defStyleAttr: Int = 0 defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) { ) : FrameLayout(context, attrs, defStyleAttr) {
private val binding = TagSelectionLayoutBinding.inflate(LayoutInflater.from(context), this)
private var filterItem: FilterItem by Delegates.notNull() private var filterItem: FilterItem by Delegates.notNull()
private var tagsContainer: ChipGroup = binding.multiLineTagGroup private var tagsContainer: ChipGroup by Delegates.notNull()
private var propertySelectedAction: PropertySelectedAction? = null private var propertySelectedAction: PropertySelectedAction? = null
private var moreValuesAction: FilterMoreAction? = null private var moreValuesAction: FilterMoreAction? = null
@ -44,82 +40,16 @@ class TagLayoutView @JvmOverloads constructor(
private var tagLayout: Int = R.layout.layout_default_tag private var tagLayout: Int = R.layout.layout_default_tag
private var moreTagText: String = "" private var moreTagText: String = ""
private var maxTagCount: Int? = null private var maxTagCount = Int.MAX_VALUE
@LayoutRes @LayoutRes
private var moreTagLayout: Int? = null private var moreTagLayout: Int = tagLayout
fun onMoreValuesAction(action: FilterMoreAction) = apply { private fun inflateAndGetChipGroup(isSingleLine: Boolean): ChipGroup {
moreValuesAction = action val layoutId = if (isSingleLine) R.layout.layout_single_line_tag_group else R.layout.layout_multi_line_tag_group
} return UiUtils.inflate(layoutId, this)
.also { addView(it) }
fun onPropertySelectedAction(action: PropertySelectedAction) = apply { .findViewById(R.id.tag_group)
propertySelectedAction = action
}
fun setMaxTagCount(count: Int) = apply {
maxTagCount = count
}
fun setSpacingHorizontal(horizontalSpacingDp: Int) = apply {
tagSpacingHorizontalDp = horizontalSpacingDp
}
fun setSpacingVertical(verticalSpacingDp: Int) = apply {
tagSpacingVerticalDp = verticalSpacingDp
}
fun setSpacing(value: Int) = apply {
tagSpacingHorizontalDp = value
tagSpacingVerticalDp = value
}
fun setSelectionType(type: SelectionType) = apply {
selectionType = type
}
fun isSingleLine(value: Boolean) = apply {
isSingleLine = value
}
fun setTagLayout(@LayoutRes layoutId: Int) = apply {
tagLayout = layoutId
}
fun setMoreTagLayout(@LayoutRes layoutId: Int, text: String) = apply {
moreTagLayout = layoutId
moreTagText = text
}
fun build(filterItem: FilterItem) {
this.filterItem = filterItem
tagsContainer = getTagView(isSingleLine)
with(tagsContainer) {
removeAllViews()
this.isSingleLine = isSingleLine
chipSpacingHorizontal = tagSpacingHorizontalDp.px
chipSpacingVertical = tagSpacingVerticalDp.px
val properties = maxTagCount
?.let { count -> filterItem.properties.take(count) }
?: filterItem.properties
properties.forEach { property ->
addView(createTag(property))
}
if (maxTagCount != null && filterItem.properties.size > maxTagCount!!) {
createMoreChip(filterItem)?.let { addView(it) }
}
}
}
private fun getTagView(isSingleLine: Boolean): ChipGroup {
binding.lineTagContainer.isVisible = isSingleLine
binding.multiLineTagGroup.isVisible = !isSingleLine
return if (isSingleLine) binding.singleLineTagGroup else binding.multiLineTagGroup
} }
private fun createTag(property: FilterProperty): TagView = private fun createTag(property: FilterProperty): TagView =
@ -138,12 +68,11 @@ class TagLayoutView @JvmOverloads constructor(
} }
} ?: throw IllegalArgumentException("Layout for tag must be extended from TagView") } ?: throw IllegalArgumentException("Layout for tag must be extended from TagView")
private fun createMoreChip(filter: FilterItem): View? = moreTagLayout?.let { private fun createMoreChip(filter: FilterItem): View? =
(UiUtils.inflate(it, this) as? TextView)?.apply { (UiUtils.inflate(moreTagLayout, this) as? TextView)?.apply {
text = moreTagText text = moreTagText
setOnClickListener { moreValuesAction?.invoke(filter) } setOnClickListener { moreValuesAction?.invoke(filter) }
} }
}
private fun clearCheck(selectedId: Int) { private fun clearCheck(selectedId: Int) {
for (i in 0 until tagsContainer.childCount) { for (i in 0 until tagsContainer.childCount) {
@ -164,4 +93,71 @@ class TagLayoutView @JvmOverloads constructor(
} }
} }
} }
inner class Builder(private val filterItem: FilterItem) {
fun onMoreValuesAction(action: FilterMoreAction) = apply {
moreValuesAction = action
}
fun onPropertySelectedAction(action: PropertySelectedAction) = apply {
propertySelectedAction = action
}
fun setMaxTagCount(count: Int) = apply {
maxTagCount = count
}
fun setSpacingHorizontal(horizontalSpacingDp: Int) = apply {
tagSpacingHorizontalDp = horizontalSpacingDp
}
fun setSpacingVertical(verticalSpacingDp: Int) = apply {
tagSpacingVerticalDp = verticalSpacingDp
}
fun setSpacing(value: Int) = apply {
tagSpacingHorizontalDp = value
tagSpacingVerticalDp = value
}
fun setSelectionType(type: SelectionType) = apply {
selectionType = type
}
fun isSingleLine(value: Boolean) = apply {
isSingleLine = value
}
fun setTagLayout(@LayoutRes layoutId: Int) = apply {
tagLayout = layoutId
}
fun setMoreTagLayout(@LayoutRes layoutId: Int, text: String) = apply {
moreTagLayout = layoutId
moreTagText = text
}
fun build() {
this@TagLayoutView.filterItem = filterItem
tagsContainer = inflateAndGetChipGroup(isSingleLine)
with(tagsContainer) {
removeAllViews()
this.isSingleLine = isSingleLine
chipSpacingHorizontal = tagSpacingHorizontalDp.px
chipSpacingVertical = tagSpacingVerticalDp.px
filterItem.properties.take(maxTagCount).forEach { property ->
addView(createTag(property))
}
if (filterItem.properties.size > maxTagCount) {
createMoreChip(filterItem)?.let { addView(it) }
}
}
}
}
} }

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.chip.ChipGroup
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/tag_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:chipSpacing="8dp"
app:selectionRequired="false"
app:singleLine="false"
app:singleSelection="true" />

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/line_tag_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:scrollbars="none">
<com.google.android.material.chip.ChipGroup
android:id="@+id/tag_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:selectionRequired="true" />
</HorizontalScrollView>

View File

@ -1,34 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<merge
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"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.chip.ChipGroup
android:id="@+id/multi_line_tag_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:selectionRequired="false"
app:singleLine="false"
app:singleSelection="true"
app:chipSpacing="8dp"/>
<HorizontalScrollView
android:id="@+id/line_tag_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:scrollbars="none"
android:visibility="gone">
<com.google.android.material.chip.ChipGroup
android:id="@+id/single_line_tag_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:selectionRequired="true"/>
</HorizontalScrollView>
</merge>

View File

@ -7,10 +7,7 @@
</style> </style>
<style name="Widget.FilterSelection.Item" parent="@style/Widget.MaterialComponents.TextView"> <style name="Widget.FilterSelection.Item" parent="@style/Widget.MaterialComponents.TextView">
<item name="android:layout_marginStart">16dp</item> <item name="android:layout_margin">16dp</item>
<item name="android:layout_marginEnd">16dp</item>
<item name="android:layout_marginTop">16dp</item>
<item name="android:layout_marginBottom">16dp</item>
</style> </style>
<style name="Widget.FilterSelection.Radio" parent="@style/Widget.MaterialComponents.CompoundButton.RadioButton"> <style name="Widget.FilterSelection.Radio" parent="@style/Widget.MaterialComponents.CompoundButton.RadioButton">