mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-23 10:01:50 +01:00
Update source filter items
TristateItem now uses TriStateCheckBox to animate between states SortItem now uses SortTextView Both views now support textAppearance & drawablePadding via xml
This commit is contained in:
parent
8b511b5708
commit
1198c2a77e
@ -1,17 +1,14 @@
|
|||||||
package eu.kanade.tachiyomi.ui.source.filter
|
package eu.kanade.tachiyomi.ui.source.filter
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.CheckedTextView
|
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractSectionableItem
|
import eu.davidea.flexibleadapter.items.AbstractSectionableItem
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
import eu.davidea.viewholders.FlexibleViewHolder
|
import eu.davidea.viewholders.FlexibleViewHolder
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.source.model.Filter
|
import eu.kanade.tachiyomi.source.model.Filter
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
import eu.kanade.tachiyomi.widget.SortTextView
|
||||||
|
|
||||||
class SortItem(val name: String, val group: SortGroup) : AbstractSectionableItem<SortItem.Holder, SortGroup>(group) {
|
class SortItem(val name: String, val group: SortGroup) : AbstractSectionableItem<SortItem.Holder, SortGroup>(group) {
|
||||||
|
|
||||||
@ -30,29 +27,17 @@ class SortItem(val name: String, val group: SortGroup) : AbstractSectionableItem
|
|||||||
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>, holder: Holder, position: Int, payloads: MutableList<Any?>?) {
|
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>, holder: Holder, position: Int, payloads: MutableList<Any?>?) {
|
||||||
val view = holder.text
|
val view = holder.text
|
||||||
view.text = name
|
view.text = name
|
||||||
|
|
||||||
val filter = group.filter
|
val filter = group.filter
|
||||||
|
|
||||||
val i = filter.values.indexOf(name)
|
val i = filter.values.indexOf(name)
|
||||||
|
view.state = when (filter.state) {
|
||||||
fun getIcon() = when (filter.state) {
|
Filter.Sort.Selection(i, false) -> SortTextView.State.DESCENDING
|
||||||
Filter.Sort.Selection(i, false) ->
|
Filter.Sort.Selection(i, true) -> SortTextView.State.ASCENDING
|
||||||
VectorDrawableCompat.create(view.resources, R.drawable.ic_arrow_downward_32dp, null)
|
else -> SortTextView.State.NONE
|
||||||
?.apply { setTint(view.context.getResourceColor(R.attr.colorAccent)) }
|
|
||||||
Filter.Sort.Selection(i, true) ->
|
|
||||||
VectorDrawableCompat.create(view.resources, R.drawable.ic_arrow_upward_32dp, null)
|
|
||||||
?.apply { setTint(view.context.getResourceColor(R.attr.colorAccent)) }
|
|
||||||
else -> ContextCompat.getDrawable(view.context, R.drawable.empty_drawable_32dp)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
view.setCompoundDrawablesWithIntrinsicBounds(getIcon(), null, null, null)
|
view.setOnSortChangeListener { _, state ->
|
||||||
holder.itemView.setOnClickListener {
|
filter.state = Filter.Sort.Selection(i, state == SortTextView.State.ASCENDING)
|
||||||
val pre = filter.state?.index ?: i
|
|
||||||
if (pre != i) {
|
|
||||||
filter.state = Filter.Sort.Selection(i, false)
|
|
||||||
} else {
|
|
||||||
filter.state = Filter.Sort.Selection(i, filter.state?.ascending == false)
|
|
||||||
}
|
|
||||||
|
|
||||||
group.subItems.forEach { adapter.notifyItemChanged(adapter.getGlobalPositionOf(it)) }
|
group.subItems.forEach { adapter.notifyItemChanged(adapter.getGlobalPositionOf(it)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -72,6 +57,6 @@ class SortItem(val name: String, val group: SortGroup) : AbstractSectionableItem
|
|||||||
|
|
||||||
class Holder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>) : FlexibleViewHolder(view, adapter) {
|
class Holder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>) : FlexibleViewHolder(view, adapter) {
|
||||||
|
|
||||||
val text: CheckedTextView = itemView.findViewById(R.id.nav_view_item)
|
val text: SortTextView = itemView.findViewById(R.id.nav_view_item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,19 @@
|
|||||||
package eu.kanade.tachiyomi.ui.source.filter
|
package eu.kanade.tachiyomi.ui.source.filter
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.CheckedTextView
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
|
|
||||||
import com.google.android.material.R
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
import eu.davidea.viewholders.FlexibleViewHolder
|
import eu.davidea.viewholders.FlexibleViewHolder
|
||||||
import eu.kanade.tachiyomi.source.model.Filter
|
import eu.kanade.tachiyomi.source.model.Filter
|
||||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
import eu.kanade.tachiyomi.widget.TriStateCheckBox
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
|
||||||
import eu.kanade.tachiyomi.R as TR
|
import eu.kanade.tachiyomi.R as TR
|
||||||
|
|
||||||
open class TriStateItem(val filter: Filter.TriState) : AbstractFlexibleItem<TriStateItem.Holder>() {
|
open class TriStateItem(val filter: Filter.TriState) : AbstractFlexibleItem<TriStateItem.Holder>() {
|
||||||
|
|
||||||
override fun getLayoutRes(): Int {
|
override fun getLayoutRes(): Int {
|
||||||
return TR.layout.navigation_view_checkedtext
|
return TR.layout.navigation_view_tristatebox
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemViewType(): Int {
|
override fun getItemViewType(): Int {
|
||||||
@ -31,30 +27,19 @@ open class TriStateItem(val filter: Filter.TriState) : AbstractFlexibleItem<TriS
|
|||||||
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>, holder: Holder, position: Int, payloads: MutableList<Any?>?) {
|
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>, holder: Holder, position: Int, payloads: MutableList<Any?>?) {
|
||||||
val view = holder.text
|
val view = holder.text
|
||||||
view.text = filter.name
|
view.text = filter.name
|
||||||
|
view.state = when (filter.state) {
|
||||||
fun getIcon() = VectorDrawableCompat.create(
|
Filter.TriState.STATE_IGNORE -> TriStateCheckBox.State.UNCHECKED
|
||||||
view.resources,
|
Filter.TriState.STATE_INCLUDE -> TriStateCheckBox.State.CHECKED
|
||||||
when (filter.state) {
|
Filter.TriState.STATE_EXCLUDE -> TriStateCheckBox.State.INVERSED
|
||||||
Filter.TriState.STATE_IGNORE -> TR.drawable.ic_check_box_outline_blank_24dp
|
else -> throw Exception("Unknown state")
|
||||||
Filter.TriState.STATE_INCLUDE -> TR.drawable.ic_check_box_24dp
|
|
||||||
Filter.TriState.STATE_EXCLUDE -> TR.drawable.ic_check_box_x_24dp
|
|
||||||
else -> throw Exception("Unknown state")
|
|
||||||
},
|
|
||||||
null
|
|
||||||
)?.apply {
|
|
||||||
val color = if (filter.state == Filter.TriState.STATE_INCLUDE) {
|
|
||||||
R.attr.colorAccent
|
|
||||||
} else {
|
|
||||||
android.R.attr.textColorSecondary
|
|
||||||
}
|
|
||||||
|
|
||||||
setTint(view.context.getResourceColor(color))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
view.setCompoundDrawablesWithIntrinsicBounds(getIcon(), null, null, null)
|
view.setOnCheckedChangeListener { _, state ->
|
||||||
holder.itemView.setOnClickListener {
|
filter.state = when (state) {
|
||||||
filter.state = (filter.state + 1) % 3
|
TriStateCheckBox.State.UNCHECKED -> Filter.TriState.STATE_IGNORE
|
||||||
view.setCompoundDrawablesWithIntrinsicBounds(getIcon(), null, null, null)
|
TriStateCheckBox.State.CHECKED -> Filter.TriState.STATE_INCLUDE
|
||||||
|
TriStateCheckBox.State.INVERSED -> Filter.TriState.STATE_EXCLUDE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,12 +55,6 @@ open class TriStateItem(val filter: Filter.TriState) : AbstractFlexibleItem<TriS
|
|||||||
|
|
||||||
class Holder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>) : FlexibleViewHolder(view, adapter) {
|
class Holder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>) : FlexibleViewHolder(view, adapter) {
|
||||||
|
|
||||||
val text: CheckedTextView = itemView.findViewById(TR.id.nav_view_item)
|
val text: TriStateCheckBox = itemView.findViewById(TR.id.nav_view_item)
|
||||||
|
|
||||||
init {
|
|
||||||
// Align with native checkbox
|
|
||||||
text.setPadding(4.dpToPx, 0, 0, 0)
|
|
||||||
text.compoundDrawablePadding = 20.dpToPx
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import android.util.AttributeSet
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.CheckBox
|
import android.widget.CheckBox
|
||||||
import android.widget.CheckedTextView
|
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import android.widget.RadioButton
|
import android.widget.RadioButton
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
@ -147,7 +146,7 @@ open class SimpleNavigationView @JvmOverloads constructor(
|
|||||||
class MultiStateHolder(parent: ViewGroup, listener: View.OnClickListener?) :
|
class MultiStateHolder(parent: ViewGroup, listener: View.OnClickListener?) :
|
||||||
ClickableHolder(parent.inflate(TR.layout.navigation_view_checkedtext), listener) {
|
ClickableHolder(parent.inflate(TR.layout.navigation_view_checkedtext), listener) {
|
||||||
|
|
||||||
val text: CheckedTextView = itemView.findViewById(TR.id.nav_view_item)
|
val text: TriStateCheckBox = itemView.findViewById(TR.id.nav_view_item)
|
||||||
}
|
}
|
||||||
|
|
||||||
class SpinnerHolder(parent: ViewGroup, listener: OnClickListener? = null) :
|
class SpinnerHolder(parent: ViewGroup, listener: OnClickListener? = null) :
|
||||||
|
@ -4,6 +4,7 @@ import android.content.Context
|
|||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
|
import androidx.core.view.updateLayoutParams
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.databinding.SortTextViewBinding
|
import eu.kanade.tachiyomi.databinding.SortTextViewBinding
|
||||||
import eu.kanade.tachiyomi.util.view.setVectorCompat
|
import eu.kanade.tachiyomi.util.view.setVectorCompat
|
||||||
@ -45,6 +46,18 @@ class SortTextView constructor(context: Context, attrs: AttributeSet?) :
|
|||||||
val maxLines = a.getInt(R.styleable.SortTextView_android_maxLines, Int.MAX_VALUE)
|
val maxLines = a.getInt(R.styleable.SortTextView_android_maxLines, Int.MAX_VALUE)
|
||||||
binding.textView.maxLines = maxLines
|
binding.textView.maxLines = maxLines
|
||||||
|
|
||||||
|
val resourceId = a.getResourceId(R.styleable.SortTextView_android_textAppearance, 0)
|
||||||
|
if (resourceId != 0) {
|
||||||
|
binding.textView.setTextAppearance(resourceId)
|
||||||
|
}
|
||||||
|
|
||||||
|
val drawablePadding = a.getDimensionPixelSize(R.styleable.SortTextView_android_drawablePadding, 0)
|
||||||
|
if (drawablePadding != 0) {
|
||||||
|
binding.textView.updateLayoutParams<MarginLayoutParams> {
|
||||||
|
marginStart = drawablePadding
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
a.recycle()
|
a.recycle()
|
||||||
|
|
||||||
setOnClickListener {
|
setOnClickListener {
|
||||||
|
@ -10,6 +10,7 @@ import eu.kanade.tachiyomi.databinding.TriStateCheckBoxBinding
|
|||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||||
import eu.kanade.tachiyomi.util.view.setAnimVectorCompat
|
import eu.kanade.tachiyomi.util.view.setAnimVectorCompat
|
||||||
import eu.kanade.tachiyomi.util.view.setVectorCompat
|
import eu.kanade.tachiyomi.util.view.setVectorCompat
|
||||||
|
import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
||||||
|
|
||||||
class TriStateCheckBox constructor(context: Context, attrs: AttributeSet?) :
|
class TriStateCheckBox constructor(context: Context, attrs: AttributeSet?) :
|
||||||
FrameLayout(context, attrs) {
|
FrameLayout(context, attrs) {
|
||||||
@ -57,6 +58,18 @@ class TriStateCheckBox constructor(context: Context, attrs: AttributeSet?) :
|
|||||||
val maxLines = a.getInt(R.styleable.TriStateCheckBox_android_maxLines, Int.MAX_VALUE)
|
val maxLines = a.getInt(R.styleable.TriStateCheckBox_android_maxLines, Int.MAX_VALUE)
|
||||||
binding.textView.maxLines = maxLines
|
binding.textView.maxLines = maxLines
|
||||||
|
|
||||||
|
val resourceId = a.getResourceId(R.styleable.TriStateCheckBox_android_textAppearance, 0)
|
||||||
|
if (resourceId != 0) {
|
||||||
|
binding.textView.setTextAppearance(resourceId)
|
||||||
|
}
|
||||||
|
|
||||||
|
val drawablePadding = a.getDimensionPixelSize(R.styleable.TriStateCheckBox_android_drawablePadding, 0)
|
||||||
|
if (drawablePadding != 0) {
|
||||||
|
binding.textView.updateLayoutParams<MarginLayoutParams> {
|
||||||
|
marginStart = drawablePadding
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
a.recycle()
|
a.recycle()
|
||||||
|
|
||||||
setOnClickListener {
|
setOnClickListener {
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
android:background="?attr/selectableItemBackground"
|
android:background="?attr/selectableItemBackground"
|
||||||
android:focusable="true">
|
android:focusable="true">
|
||||||
|
|
||||||
<CheckBox
|
<com.google.android.material.checkbox.MaterialCheckBox
|
||||||
android:id="@+id/nav_view_item"
|
android:id="@+id/nav_view_item"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
@ -17,7 +17,6 @@
|
|||||||
android:background="@android:color/transparent"
|
android:background="@android:color/transparent"
|
||||||
android:gravity="center_vertical|start"
|
android:gravity="center_vertical|start"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:clickable="false"
|
android:clickable="false" />
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body2" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -1,21 +1,19 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/listPreferredItemHeightSmall"
|
android:layout_height="?attr/listPreferredItemHeightSmall"
|
||||||
android:paddingStart="?attr/listPreferredItemPaddingStart"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:paddingEnd="?attr/listPreferredItemPaddingEnd"
|
|
||||||
android:background="?attr/selectableItemBackground"
|
android:background="?attr/selectableItemBackground"
|
||||||
android:focusable="true">
|
android:focusable="true">
|
||||||
|
|
||||||
<CheckedTextView
|
<eu.kanade.tachiyomi.widget.SortTextView
|
||||||
android:id="@+id/nav_view_item"
|
android:id="@+id/nav_view_item"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:drawablePadding="@dimen/material_component_lists_icon_left_padding"
|
android:drawablePadding="@dimen/material_component_lists_icon_left_padding"
|
||||||
|
tools:text="Sorting by"
|
||||||
android:gravity="center_vertical|start"
|
android:gravity="center_vertical|start"
|
||||||
android:maxLines="1"
|
android:maxLines="1" />
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body2" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
21
app/src/main/res/layout/navigation_view_tristatebox.xml
Normal file
21
app/src/main/res/layout/navigation_view_tristatebox.xml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/listPreferredItemHeightSmall"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:paddingStart="?attr/listPreferredItemPaddingStart"
|
||||||
|
android:paddingEnd="?attr/listPreferredItemPaddingEnd"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:focusable="true">
|
||||||
|
|
||||||
|
<eu.kanade.tachiyomi.widget.TriStateCheckBox
|
||||||
|
android:id="@+id/nav_view_item"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:drawablePadding="@dimen/material_component_lists_icon_left_padding"
|
||||||
|
android:gravity="center_vertical|start"
|
||||||
|
android:maxLines="1"
|
||||||
|
tools:text="Item" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -31,12 +31,16 @@
|
|||||||
<declare-styleable name="TriStateCheckBox">
|
<declare-styleable name="TriStateCheckBox">
|
||||||
<attr name="android:text" format="reference|string"/>
|
<attr name="android:text" format="reference|string"/>
|
||||||
<attr name="android:maxLines"/>
|
<attr name="android:maxLines"/>
|
||||||
|
<attr name="android:textAppearance"/>
|
||||||
|
<attr name="android:drawablePadding"/>
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
|
|
||||||
|
|
||||||
<declare-styleable name="SortTextView">
|
<declare-styleable name="SortTextView">
|
||||||
<attr name="android:text" format="reference|string"/>
|
<attr name="android:text" format="reference|string"/>
|
||||||
<attr name="android:maxLines"/>
|
<attr name="android:maxLines"/>
|
||||||
|
<attr name="android:textAppearance"/>
|
||||||
|
<attr name="android:drawablePadding"/>
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
|
|
||||||
<declare-styleable name="MenuSheetItemView">
|
<declare-styleable name="MenuSheetItemView">
|
||||||
|
Loading…
Reference in New Issue
Block a user