mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-23 23:51:53 +01:00
Updates to the Source Filter Sheet
With some renaming, but mostly taking changes from upstream + some from the new set categories sheet (such as reset/filter at the bottom Co-Authored-By: arkon <4098258+arkon@users.noreply.github.com>
This commit is contained in:
parent
0afe075f46
commit
41f3d1ea2a
@ -289,7 +289,7 @@ open class BrowseSourceController(bundle: Bundle) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun showFilters() {
|
private fun showFilters() {
|
||||||
val sheet = SourceSearchSheet(activity!!)
|
val sheet = SourceFilterSheet(activity!!)
|
||||||
sheet.setFilters(presenter.filterItems)
|
sheet.setFilters(presenter.filterItems)
|
||||||
presenter.filtersChanged = false
|
presenter.filtersChanged = false
|
||||||
val oldFilters = mutableListOf<Any?>()
|
val oldFilters = mutableListOf<Any?>()
|
||||||
|
@ -0,0 +1,150 @@
|
|||||||
|
package eu.kanade.tachiyomi.ui.source.browse
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.view.ViewTreeObserver.OnGlobalLayoutListener
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.databinding.SourceFilterSheetBinding
|
||||||
|
import eu.kanade.tachiyomi.util.system.dpToPx
|
||||||
|
import eu.kanade.tachiyomi.util.view.collapse
|
||||||
|
import eu.kanade.tachiyomi.util.view.setEdgeToEdge
|
||||||
|
import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
||||||
|
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
|
||||||
|
|
||||||
|
class SourceFilterSheet(val activity: Activity) :
|
||||||
|
BottomSheetDialog(activity, R.style.BottomSheetDialogTheme) {
|
||||||
|
|
||||||
|
private val sheetBehavior: BottomSheetBehavior<*>
|
||||||
|
|
||||||
|
private var filterChanged = true
|
||||||
|
|
||||||
|
val adapter: FlexibleAdapter<IFlexible<*>> = FlexibleAdapter<IFlexible<*>>(null)
|
||||||
|
.setDisplayHeadersAtStartUp(true)
|
||||||
|
|
||||||
|
var onSearchClicked = {}
|
||||||
|
|
||||||
|
var onResetClicked = {}
|
||||||
|
|
||||||
|
private val binding = SourceFilterSheetBinding.inflate(activity.layoutInflater)
|
||||||
|
init {
|
||||||
|
setContentView(binding.root)
|
||||||
|
binding.searchBtn.setOnClickListener { dismiss() }
|
||||||
|
binding.resetBtn.setOnClickListener { onResetClicked() }
|
||||||
|
|
||||||
|
sheetBehavior = BottomSheetBehavior.from(binding.root.parent as ViewGroup)
|
||||||
|
sheetBehavior.peekHeight = 450.dpToPx
|
||||||
|
sheetBehavior.collapse()
|
||||||
|
setEdgeToEdge(activity, binding.root)
|
||||||
|
|
||||||
|
binding.titleLayout.viewTreeObserver.addOnGlobalLayoutListener(object : OnGlobalLayoutListener {
|
||||||
|
override fun onGlobalLayout() {
|
||||||
|
binding.cardView.updateLayoutParams<ConstraintLayout.LayoutParams> {
|
||||||
|
val fullHeight = activity.window.decorView.height
|
||||||
|
val insets = activity.window.decorView.rootWindowInsets
|
||||||
|
matchConstraintMaxHeight =
|
||||||
|
fullHeight - (insets?.systemWindowInsetTop ?: 0) -
|
||||||
|
binding.titleLayout.height - 75.dpToPx
|
||||||
|
}
|
||||||
|
if (binding.titleLayout.height > 0) {
|
||||||
|
binding.titleLayout.viewTreeObserver.removeOnGlobalLayoutListener(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
(binding.root.parent.parent as? View)?.viewTreeObserver?.addOnGlobalLayoutListener(object : OnGlobalLayoutListener {
|
||||||
|
override fun onGlobalLayout() {
|
||||||
|
updateBottomButtons()
|
||||||
|
if (sheetBehavior.state != BottomSheetBehavior.STATE_COLLAPSED) {
|
||||||
|
(binding.root.parent.parent as? View)?.viewTreeObserver?.removeOnGlobalLayoutListener(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
setOnShowListener {
|
||||||
|
updateBottomButtons()
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.filtersRecycler.layoutManager = androidx.recyclerview.widget.LinearLayoutManager(context)
|
||||||
|
binding.filtersRecycler.clipToPadding = false
|
||||||
|
binding.filtersRecycler.adapter = adapter
|
||||||
|
binding.filtersRecycler.setHasFixedSize(true)
|
||||||
|
|
||||||
|
sheetBehavior.addBottomSheetCallback(
|
||||||
|
object : BottomSheetBehavior.BottomSheetCallback() {
|
||||||
|
override fun onSlide(bottomSheet: View, progress: Float) {
|
||||||
|
updateBottomButtons()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStateChanged(p0: View, state: Int) {
|
||||||
|
updateBottomButtons()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
binding.filtersRecycler.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||||
|
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||||
|
super.onScrollStateChanged(recyclerView, newState)
|
||||||
|
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
|
||||||
|
sheetBehavior.isDraggable = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||||
|
super.onScrolled(recyclerView, dx, dy)
|
||||||
|
if (recyclerView.canScrollVertically(-1)) {
|
||||||
|
sheetBehavior.isDraggable = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
sheetBehavior.collapse()
|
||||||
|
updateBottomButtons()
|
||||||
|
binding.root.post {
|
||||||
|
updateBottomButtons()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
val attrsArray = intArrayOf(android.R.attr.actionBarSize)
|
||||||
|
val array = context.obtainStyledAttributes(attrsArray)
|
||||||
|
val headerHeight = array.getDimensionPixelSize(0, 0)
|
||||||
|
binding.titleLayout.updatePaddingRelative(
|
||||||
|
bottom = activity.window.decorView.rootWindowInsets.systemWindowInsetBottom
|
||||||
|
)
|
||||||
|
|
||||||
|
binding.titleLayout.updateLayoutParams<ConstraintLayout.LayoutParams> {
|
||||||
|
height = headerHeight + binding.titleLayout.paddingBottom
|
||||||
|
}
|
||||||
|
array.recycle()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateBottomButtons() {
|
||||||
|
val bottomSheet = binding.root.parent as View
|
||||||
|
val bottomSheetVisibleHeight = -bottomSheet.top + (activity.window.decorView.height - bottomSheet.height)
|
||||||
|
|
||||||
|
binding.titleLayout.translationY = bottomSheetVisibleHeight.toFloat()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dismiss() {
|
||||||
|
super.dismiss()
|
||||||
|
if (filterChanged) {
|
||||||
|
onSearchClicked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setFilters(items: List<IFlexible<*>>) {
|
||||||
|
adapter.updateDataSet(items)
|
||||||
|
}
|
||||||
|
}
|
@ -1,130 +0,0 @@
|
|||||||
package eu.kanade.tachiyomi.ui.source.browse
|
|
||||||
|
|
||||||
import android.animation.ObjectAnimator
|
|
||||||
import android.animation.ValueAnimator
|
|
||||||
import android.app.Activity
|
|
||||||
import android.view.ActionMode
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
|
||||||
import eu.kanade.tachiyomi.R
|
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
|
||||||
import eu.kanade.tachiyomi.databinding.SourceFilterSheetBinding
|
|
||||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
|
||||||
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
|
|
||||||
import eu.kanade.tachiyomi.util.view.expand
|
|
||||||
import eu.kanade.tachiyomi.util.view.setEdgeToEdge
|
|
||||||
import uy.kohesive.injekt.injectLazy
|
|
||||||
|
|
||||||
class SourceSearchSheet(activity: Activity) :
|
|
||||||
BottomSheetDialog(activity, R.style.BottomSheetDialogTheme) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Preferences helper.
|
|
||||||
*/
|
|
||||||
private val preferences by injectLazy<PreferencesHelper>()
|
|
||||||
|
|
||||||
private var sheetBehavior: BottomSheetBehavior<*>
|
|
||||||
|
|
||||||
private var elevationAnimator: ValueAnimator? = null
|
|
||||||
|
|
||||||
var filterChanged = true
|
|
||||||
|
|
||||||
var isNotElevated = false
|
|
||||||
|
|
||||||
val adapter: FlexibleAdapter<IFlexible<*>> = FlexibleAdapter<IFlexible<*>>(null)
|
|
||||||
.setDisplayHeadersAtStartUp(true)
|
|
||||||
|
|
||||||
var onSearchClicked = {}
|
|
||||||
|
|
||||||
var onResetClicked = {}
|
|
||||||
|
|
||||||
private val binding = SourceFilterSheetBinding.inflate(activity.layoutInflater)
|
|
||||||
init {
|
|
||||||
setContentView(binding.root)
|
|
||||||
binding.toolbarTitle.text = context.getString(R.string.search_filters)
|
|
||||||
binding.searchBtn.setOnClickListener { dismiss() }
|
|
||||||
binding.resetBtn.setOnClickListener { onResetClicked() }
|
|
||||||
|
|
||||||
sheetBehavior = BottomSheetBehavior.from(binding.root.parent as ViewGroup)
|
|
||||||
sheetBehavior.skipCollapsed = true
|
|
||||||
sheetBehavior.expand()
|
|
||||||
setEdgeToEdge(
|
|
||||||
activity,
|
|
||||||
binding.root,
|
|
||||||
50.dpToPx
|
|
||||||
)
|
|
||||||
|
|
||||||
binding.recycler.layoutManager = androidx.recyclerview.widget.LinearLayoutManager(context)
|
|
||||||
binding.recycler.clipToPadding = false
|
|
||||||
binding.recycler.adapter = adapter
|
|
||||||
binding.recycler.setHasFixedSize(true)
|
|
||||||
binding.recycler.setOnApplyWindowInsetsListener(RecyclerWindowInsetsListener)
|
|
||||||
|
|
||||||
// the spinner in the recycler can break the sheet's layout on change
|
|
||||||
// this is to reset it back
|
|
||||||
binding.sourceFilterSheet.post {
|
|
||||||
(binding.sourceFilterSheet.parent as? View)?.fitsSystemWindows = false
|
|
||||||
binding.sourceFilterSheet.viewTreeObserver.addOnDrawListener {
|
|
||||||
(binding.sourceFilterSheet.parent as? View)?.fitsSystemWindows = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sheetBehavior.addBottomSheetCallback(
|
|
||||||
object : BottomSheetBehavior.BottomSheetCallback() {
|
|
||||||
override fun onSlide(bottomSheet: View, progress: Float) {}
|
|
||||||
|
|
||||||
override fun onStateChanged(p0: View, state: Int) {
|
|
||||||
if (state == BottomSheetBehavior.STATE_EXPANDED) {
|
|
||||||
sheetBehavior.skipCollapsed = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
binding.recycler.addOnScrollListener(
|
|
||||||
object : RecyclerView.OnScrollListener() {
|
|
||||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
|
||||||
super.onScrolled(recyclerView, dx, dy)
|
|
||||||
val atTop = !binding.recycler.canScrollVertically(-1)
|
|
||||||
if (atTop != isNotElevated) {
|
|
||||||
elevationAnimator?.cancel()
|
|
||||||
isNotElevated = atTop
|
|
||||||
elevationAnimator?.cancel()
|
|
||||||
elevationAnimator = ObjectAnimator.ofFloat(
|
|
||||||
binding.titleLayout,
|
|
||||||
"elevation",
|
|
||||||
binding.titleLayout.elevation,
|
|
||||||
if (atTop) 0f else 10f.dpToPx
|
|
||||||
)
|
|
||||||
elevationAnimator?.duration = 100
|
|
||||||
elevationAnimator?.start()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onWindowStartingActionMode(
|
|
||||||
callback: ActionMode.Callback?,
|
|
||||||
type: Int
|
|
||||||
): ActionMode? {
|
|
||||||
(binding.sourceFilterSheet.parent as View).fitsSystemWindows = false
|
|
||||||
return super.onWindowStartingActionMode(callback, type)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun dismiss() {
|
|
||||||
super.dismiss()
|
|
||||||
if (filterChanged) {
|
|
||||||
onSearchClicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setFilters(items: List<IFlexible<*>>) {
|
|
||||||
adapter.updateDataSet(items)
|
|
||||||
}
|
|
||||||
}
|
|
@ -36,9 +36,9 @@ class GroupItem(val filter: Filter.Group<*>) : AbstractExpandableHeaderItem<Grou
|
|||||||
|
|
||||||
holder.icon.setVectorCompat(
|
holder.icon.setVectorCompat(
|
||||||
if (isExpanded) {
|
if (isExpanded) {
|
||||||
R.drawable.ic_expand_more_24dp
|
R.drawable.ic_expand_less_24dp
|
||||||
} else {
|
} else {
|
||||||
R.drawable.ic_chevron_right_24dp
|
R.drawable.ic_expand_more_24dp
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
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.ArrayAdapter
|
|
||||||
import android.widget.Spinner
|
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
@ -11,7 +8,7 @@ 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.widget.IgnoreFirstSpinnerListener
|
import eu.kanade.tachiyomi.widget.MaterialSpinnerView
|
||||||
|
|
||||||
open class SelectItem(val filter: Filter.Select<*>) : AbstractFlexibleItem<SelectItem.Holder>() {
|
open class SelectItem(val filter: Filter.Select<*>) : AbstractFlexibleItem<SelectItem.Holder>() {
|
||||||
|
|
||||||
@ -24,21 +21,13 @@ open class SelectItem(val filter: Filter.Select<*>) : AbstractFlexibleItem<Selec
|
|||||||
}
|
}
|
||||||
|
|
||||||
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?>?) {
|
||||||
holder.text.text = filter.name + ": "
|
holder.spinnerView.title = filter.name + ": "
|
||||||
|
|
||||||
val spinner = holder.spinner
|
holder.spinnerView.setEntries(filter.values.map { it.toString() })
|
||||||
spinner.prompt = filter.name
|
holder.spinnerView.setSelection(filter.state)
|
||||||
spinner.adapter = ArrayAdapter<Any>(
|
holder.spinnerView.onItemSelectedListener = { pos ->
|
||||||
holder.itemView.context,
|
|
||||||
android.R.layout.simple_spinner_item,
|
|
||||||
filter.values
|
|
||||||
).apply {
|
|
||||||
setDropDownViewResource(R.layout.common_spinner_item)
|
|
||||||
}
|
|
||||||
spinner.onItemSelectedListener = IgnoreFirstSpinnerListener { pos ->
|
|
||||||
filter.state = pos
|
filter.state = pos
|
||||||
}
|
}
|
||||||
spinner.setSelection(filter.state)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
@ -52,8 +41,6 @@ open class SelectItem(val filter: Filter.Select<*>) : AbstractFlexibleItem<Selec
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 spinnerView: MaterialSpinnerView = itemView.findViewById(R.id.nav_view_item)
|
||||||
val text: TextView = itemView.findViewById(R.id.nav_view_item_text)
|
|
||||||
val spinner: Spinner = itemView.findViewById(R.id.nav_view_item)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,9 +33,9 @@ class SortGroup(val filter: Filter.Sort) : AbstractExpandableHeaderItem<SortGrou
|
|||||||
|
|
||||||
holder.icon.setVectorCompat(
|
holder.icon.setVectorCompat(
|
||||||
if (isExpanded) {
|
if (isExpanded) {
|
||||||
R.drawable.ic_expand_more_24dp
|
R.drawable.ic_expand_less_24dp
|
||||||
} else {
|
} else {
|
||||||
R.drawable.ic_chevron_right_24dp
|
R.drawable.ic_expand_more_24dp
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -56,23 +56,34 @@ class MaterialSpinnerView @JvmOverloads constructor(context: Context, attrs: Att
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
addView(binding.root)
|
addView(binding.root)
|
||||||
val a = context.obtainStyledAttributes(attrs, R.styleable.ReaderSpinnerView, 0, 0)
|
val a = context.obtainStyledAttributes(attrs, R.styleable.MaterialSpinnerView, 0, 0)
|
||||||
|
|
||||||
val str = a.getString(R.styleable.ReaderSpinnerView_title) ?: ""
|
val str = a.getString(R.styleable.MaterialSpinnerView_title) ?: ""
|
||||||
title = str
|
title = str
|
||||||
|
|
||||||
val entries = (a.getTextArray(R.styleable.ReaderSpinnerView_android_entries) ?: emptyArray()).map { it.toString() }
|
val entries = (a.getTextArray(R.styleable.MaterialSpinnerView_android_entries) ?: emptyArray()).map { it.toString() }
|
||||||
this.entries = entries
|
this.entries = entries
|
||||||
|
|
||||||
binding.detailView.text = entries.firstOrNull().orEmpty()
|
binding.detailView.text = entries.firstOrNull().orEmpty()
|
||||||
|
|
||||||
|
if (entries.isNotEmpty()) {
|
||||||
|
popup = makeSettingsPopup()
|
||||||
|
setOnTouchListener(popup?.dragToOpenListener)
|
||||||
|
setOnClickListener {
|
||||||
|
popup?.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a.recycle()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setEntries(entries: List<String>) {
|
||||||
|
this.entries = entries
|
||||||
popup = makeSettingsPopup()
|
popup = makeSettingsPopup()
|
||||||
setOnTouchListener(popup?.dragToOpenListener)
|
setOnTouchListener(popup?.dragToOpenListener)
|
||||||
setOnClickListener {
|
setOnClickListener {
|
||||||
popup?.show()
|
popup?.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
a.recycle()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setSelection(selection: Int) {
|
fun setSelection(selection: Int) {
|
||||||
|
@ -9,7 +9,6 @@ import android.widget.CheckBox
|
|||||||
import android.widget.CheckedTextView
|
import android.widget.CheckedTextView
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import android.widget.RadioButton
|
import android.widget.RadioButton
|
||||||
import android.widget.Spinner
|
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.appcompat.widget.TintTypedArray
|
import androidx.appcompat.widget.TintTypedArray
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
@ -154,8 +153,7 @@ open class SimpleNavigationView @JvmOverloads constructor(
|
|||||||
class SpinnerHolder(parent: ViewGroup, listener: OnClickListener? = null) :
|
class SpinnerHolder(parent: ViewGroup, listener: OnClickListener? = null) :
|
||||||
ClickableHolder(parent.inflate(TR.layout.navigation_view_spinner), listener) {
|
ClickableHolder(parent.inflate(TR.layout.navigation_view_spinner), listener) {
|
||||||
|
|
||||||
val text: TextView = itemView.findViewById(TR.id.nav_view_item_text)
|
val spinnerView: MaterialSpinnerView = itemView.findViewById(TR.id.nav_view_item)
|
||||||
val spinner: Spinner = itemView.findViewById(TR.id.nav_view_item)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class EditTextHolder(parent: ViewGroup) :
|
class EditTextHolder(parent: ViewGroup) :
|
||||||
|
@ -1,30 +1,33 @@
|
|||||||
<?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"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/listPreferredItemHeightSmall"
|
android:layout_height="?attr/listPreferredItemHeightSmall"
|
||||||
android:background="?colorPrimaryVariant"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
|
android:background="?android:attr/colorBackground"
|
||||||
|
android:orientation="horizontal"
|
||||||
android:paddingStart="?attr/listPreferredItemPaddingStart"
|
android:paddingStart="?attr/listPreferredItemPaddingStart"
|
||||||
android:paddingEnd="?attr/listPreferredItemPaddingEnd"
|
android:paddingEnd="?attr/listPreferredItemPaddingEnd">
|
||||||
android:elevation="2dp">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/title"
|
android:id="@+id/title"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
|
android:textAllCaps="true"
|
||||||
android:textColor="?attr/actionBarTintColor"
|
android:textSize="15sp"
|
||||||
tools:text="Header"/>
|
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
tools:text="Header" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/expand_icon"
|
android:id="@+id/expand_icon"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"/>
|
android:layout_height="wrap_content"
|
||||||
|
tools:src="@drawable/ic_expand_more_24dp"
|
||||||
|
app:tint="?android:attr/textColorPrimary" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/listPreferredItemHeightSmall"
|
android:layout_height="?attr/listPreferredItemHeightSmall"
|
||||||
@ -9,24 +8,12 @@
|
|||||||
android:background="?attr/selectableItemBackground"
|
android:background="?attr/selectableItemBackground"
|
||||||
android:focusable="true">
|
android:focusable="true">
|
||||||
|
|
||||||
<TextView
|
<eu.kanade.tachiyomi.widget.MaterialSpinnerView
|
||||||
android:id="@+id/nav_view_item_text"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:paddingEnd="8dp"
|
|
||||||
tools:text="Filter:" />
|
|
||||||
|
|
||||||
<Spinner
|
|
||||||
android:id="@+id/nav_view_item"
|
android:id="@+id/nav_view_item"
|
||||||
android:layout_width="0dp"
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
tools:entries="@array/viewers_selector"
|
||||||
android:gravity="center_vertical|start"
|
tools:title="Filter: "/>
|
||||||
android:maxLines="1"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body2" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
</FrameLayout>
|
||||||
|
@ -1,19 +1,40 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/source_filter_sheet"
|
android:id="@+id/source_filter_sheet"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:background="@drawable/bottom_sheet_rounded_background"
|
android:background="@drawable/bottom_sheet_rounded_background"
|
||||||
|
app:layout_constraintVertical_chainStyle="packed"
|
||||||
android:backgroundTint="?android:attr/colorBackground">
|
android:backgroundTint="?android:attr/colorBackground">
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.cardview.widget.CardView
|
||||||
android:id="@+id/recycler"
|
android:id="@+id/card_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="?attr/actionBarSize"
|
app:layout_constraintBottom_toTopOf="@id/title_layout"
|
||||||
android:clipToPadding="false" />
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:cardCornerRadius="@dimen/rounded_radius"
|
||||||
|
app:cardElevation="0dp"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/filters_recycler"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingTop="12dp"
|
||||||
|
android:paddingBottom="12dp"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:background="@drawable/bottom_sheet_rounded_background"
|
||||||
|
android:backgroundTint="?attr/colorSecondary"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/title_layout"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/title_layout"
|
android:id="@+id/title_layout"
|
||||||
@ -23,49 +44,49 @@
|
|||||||
android:background="@drawable/bottom_sheet_rounded_background"
|
android:background="@drawable/bottom_sheet_rounded_background"
|
||||||
android:backgroundTint="?attr/colorSecondary"
|
android:backgroundTint="?attr/colorSecondary"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:elevation="0dp"
|
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/card_view"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/reset_btn"
|
android:id="@+id/reset_btn"
|
||||||
style="@style/Theme.Widget.Button.TextButton"
|
style="@style/Theme.Widget.Button.TextButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:textColor="?attr/tabBarIconColor"
|
android:layout_height="wrap_content"
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:textSize="16sp"
|
|
||||||
android:letterSpacing="0.0"
|
|
||||||
android:text="@string/reset"
|
android:text="@string/reset"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/search_btn"
|
||||||
|
app:layout_constraintHorizontal_chainStyle="spread_inside"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
android:id="@+id/toolbar_title"
|
|
||||||
style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:textColor="?actionBarTintColor"
|
|
||||||
android:textSize="20sp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
tools:text="Title Text" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/search_btn"
|
android:id="@+id/search_btn"
|
||||||
style="@style/Theme.Widget.Button.TextButton"
|
style="@style/Theme.Widget.Button.Primary"
|
||||||
android:textSize="16sp"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:textColor="?attr/tabBarIconColor"
|
android:layout_height="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_marginStart="48dp"
|
||||||
android:text="@string/search"
|
android:layout_marginEnd="16dp"
|
||||||
|
android:text="@string/filter"
|
||||||
|
app:flow_verticalBias="1.0"
|
||||||
|
app:iconTint="?colorAccent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintHorizontal_chainStyle="spread"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/reset_btn"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintWidth_min="150dp" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/bottom_divider"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
android:background="@color/divider"/>
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</FrameLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
<attr name="tabBarIconInactive" format="reference|integer"/>
|
<attr name="tabBarIconInactive" format="reference|integer"/>
|
||||||
<attr name="tabHighlightBackground" format="color"/>
|
<attr name="tabHighlightBackground" format="color"/>
|
||||||
|
|
||||||
<declare-styleable name="ReaderSpinnerView">
|
<declare-styleable name="MaterialSpinnerView">
|
||||||
<attr name="title" format="reference|string"/>
|
<attr name="title" format="reference|string"/>
|
||||||
<attr name="android:entries"/>
|
<attr name="android:entries"/>
|
||||||
<attr name="summary" format="reference|string" />
|
<attr name="summary" format="reference|string" />
|
||||||
|
Loading…
Reference in New Issue
Block a user