mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-24 01:31:50 +01:00
Library toolbar now collaspses again
Moved the show all categories button into the recylcer
This commit is contained in:
parent
f890f5cfff
commit
ee2df0f87a
@ -61,11 +61,10 @@ import eu.kanade.tachiyomi.util.system.dpToPxEnd
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
import eu.kanade.tachiyomi.util.system.launchUI
|
||||
import eu.kanade.tachiyomi.util.view.applyWindowInsetsForRootController
|
||||
import eu.kanade.tachiyomi.util.view.doOnApplyWindowInsets
|
||||
import eu.kanade.tachiyomi.util.view.getItemView
|
||||
import eu.kanade.tachiyomi.util.view.gone
|
||||
import eu.kanade.tachiyomi.util.view.hide
|
||||
import eu.kanade.tachiyomi.util.view.marginTop
|
||||
import eu.kanade.tachiyomi.util.view.scrollViewWith
|
||||
import eu.kanade.tachiyomi.util.view.setBackground
|
||||
import eu.kanade.tachiyomi.util.view.setOnQueryTextChangeListener
|
||||
import eu.kanade.tachiyomi.util.view.setStartTranslationX
|
||||
@ -245,12 +244,6 @@ class LibraryController(
|
||||
fast_scroller.setStartTranslationX(!alwaysShowScroller)
|
||||
fast_scroller.setBackground(!alwaysShowScroller)
|
||||
|
||||
show_all.isChecked = preferences.showAllCategories().get()
|
||||
show_all.setOnCheckedChangeListener { _, isChecked ->
|
||||
preferences.showAllCategories().set(isChecked)
|
||||
presenter.getLibrary()
|
||||
}
|
||||
|
||||
adapter = LibraryCategoryAdapter(this)
|
||||
adapter.expandItemsAtStartUp()
|
||||
adapter.isRecursiveCollapse = true
|
||||
@ -312,7 +305,15 @@ class LibraryController(
|
||||
appbar?.y = 0f
|
||||
recycler.suppressLayout(true)
|
||||
(recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(
|
||||
itemPosition, 0
|
||||
itemPosition, if (adapter.isSingleCategory) {
|
||||
0
|
||||
} else {
|
||||
if (itemPosition == 0) {
|
||||
0
|
||||
} else {
|
||||
(-40).dpToPx
|
||||
}
|
||||
}
|
||||
)
|
||||
recycler.suppressLayout(false)
|
||||
}
|
||||
@ -330,25 +331,18 @@ class LibraryController(
|
||||
scrollToHeader(it)
|
||||
showCategories(false)
|
||||
}
|
||||
swipe_refresh.setDistanceToTriggerSync(150.dpToPx)
|
||||
val marginTop = category_layout.marginTop
|
||||
recycler.doOnApplyWindowInsets { recyclerView, insets, _ ->
|
||||
recyclerView.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
topMargin = marginTop + insets.systemWindowInsetTop
|
||||
category_recycler.onShowAllClicked = { isChecked ->
|
||||
preferences.showAllCategories().set(isChecked)
|
||||
presenter.getLibrary()
|
||||
}
|
||||
scrollViewWith(recycler, swipeRefreshLayout = swipe_refresh, afterInsets = { insets ->
|
||||
category_layout?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
topMargin = marginTop + insets.systemWindowInsetTop
|
||||
}
|
||||
recycler_cover?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
topMargin = marginTop + insets.systemWindowInsetTop
|
||||
topMargin = recycler?.paddingTop ?: 0
|
||||
}
|
||||
fast_scroller?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
topMargin = insets.systemWindowInsetTop
|
||||
}
|
||||
swipe_refresh?.setProgressViewOffset(
|
||||
true, (marginTop + insets.systemWindowInsetTop) + (-60).dpToPx, marginTop + insets.systemWindowInsetTop + 10.dpToPx
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
swipe_refresh.setOnRefreshListener {
|
||||
swipe_refresh.isRefreshing = false
|
||||
@ -605,11 +599,16 @@ class LibraryController(
|
||||
private fun showCategories(show: Boolean) {
|
||||
recycler_cover.isClickable = show
|
||||
recycler_cover.isFocusable = show
|
||||
val translateY = if (show) category_layout.height.toFloat() + 12f.dpToPx else 0f
|
||||
val translateY = if (show) {
|
||||
category_layout.height.toFloat() + recycler.paddingTop
|
||||
} else {
|
||||
0f
|
||||
}
|
||||
recycler.animate().translationY(translateY).start()
|
||||
recycler_cover.animate().translationY(translateY).start()
|
||||
recycler_cover.animate().alpha(if (show) 0.75f else 0f).start()
|
||||
if (show) {
|
||||
activity?.appbar?.y = 0f
|
||||
elevateFunc(false)
|
||||
activity?.dropdown?.setImageResource(R.drawable.ic_arrow_drop_up_24dp)
|
||||
} else {
|
||||
|
@ -1,25 +1,41 @@
|
||||
package eu.kanade.tachiyomi.ui.library.category
|
||||
|
||||
import android.view.View
|
||||
import android.widget.CheckBox
|
||||
import android.widget.TextView
|
||||
import com.mikepenz.fastadapter.FastAdapter
|
||||
import com.mikepenz.fastadapter.items.AbstractItem
|
||||
import com.tfcporciuncula.flow.Preference
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
class CategoryItem(val category: Category) :
|
||||
AbstractItem<CategoryItem.ViewHolder>() {
|
||||
class CategoryItem(val category: Category) : AbstractItem<FastAdapter.ViewHolder<CategoryItem>>() {
|
||||
|
||||
/** defines the type defining this item. must be unique. preferably an id */
|
||||
override val type: Int = R.id.category_text
|
||||
override val type: Int = if (category.id == -1) {
|
||||
R.id.auto_checkbox
|
||||
} else {
|
||||
R.id.category_text
|
||||
}
|
||||
|
||||
/** defines the layout which will be used for this item in the list */
|
||||
override val layoutRes: Int = R.layout.catergory_text_view
|
||||
override val layoutRes: Int = if (category.id == -1) {
|
||||
R.layout.auto_ext_checkbox
|
||||
} else {
|
||||
R.layout.catergory_text_view
|
||||
}
|
||||
|
||||
override var identifier = category.id?.toLong() ?: -1L
|
||||
|
||||
override fun getViewHolder(v: View): ViewHolder {
|
||||
return ViewHolder(v)
|
||||
override fun getViewHolder(v: View): FastAdapter.ViewHolder<CategoryItem> {
|
||||
return if (category.id == -1) {
|
||||
ShowAllViewHolder(Injekt.get<PreferencesHelper>().showAllCategories(), v)
|
||||
} else {
|
||||
ViewHolder(v)
|
||||
}
|
||||
}
|
||||
|
||||
class ViewHolder(view: View) : FastAdapter.ViewHolder<CategoryItem>(view) {
|
||||
@ -33,4 +49,19 @@ AbstractItem<CategoryItem.ViewHolder>() {
|
||||
categoryTitle.text = null
|
||||
}
|
||||
}
|
||||
|
||||
class ShowAllViewHolder(val pref: Preference<Boolean>, view: View) :
|
||||
FastAdapter.ViewHolder<CategoryItem>(view) {
|
||||
|
||||
val checkbox: CheckBox? = view.findViewById(R.id.auto_checkbox)
|
||||
|
||||
init {
|
||||
checkbox?.setText(R.string.show_all_categories)
|
||||
}
|
||||
|
||||
override fun bindView(item: CategoryItem, payloads: List<Any>) {
|
||||
checkbox?.isChecked = pref.get()
|
||||
}
|
||||
override fun unbindView(item: CategoryItem) {}
|
||||
}
|
||||
}
|
||||
|
@ -2,16 +2,19 @@ package eu.kanade.tachiyomi.ui.library.category
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.CheckBox
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.mikepenz.fastadapter.FastAdapter
|
||||
import com.mikepenz.fastadapter.adapters.ItemAdapter
|
||||
import com.mikepenz.fastadapter.listeners.CustomEventHook
|
||||
import com.mikepenz.fastadapter.listeners.OnBindViewHolderListenerImpl
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
import eu.kanade.tachiyomi.data.database.models.CategoryImpl
|
||||
import eu.kanade.tachiyomi.util.view.marginBottom
|
||||
import eu.kanade.tachiyomi.util.view.marginTop
|
||||
|
||||
class CategoryRecyclerView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
@ -21,8 +24,12 @@ class CategoryRecyclerView @JvmOverloads constructor(
|
||||
val manager = LinearLayoutManager(context)
|
||||
private val fastAdapter: FastAdapter<CategoryItem>
|
||||
var onCategoryClicked: (Int) -> Unit = { _ -> }
|
||||
var onShowAllClicked: (Boolean) -> Unit = { }
|
||||
private val itemAdapter = ItemAdapter<CategoryItem>()
|
||||
var selectedCategory: Int = 0
|
||||
val headerItem = CategoryItem(CategoryImpl().apply {
|
||||
id = -1
|
||||
})
|
||||
|
||||
init {
|
||||
fastAdapter = FastAdapter.with(itemAdapter)
|
||||
@ -31,8 +38,9 @@ class CategoryRecyclerView @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
fun setCategories(items: List<Category>) {
|
||||
itemAdapter.set(items.map(::CategoryItem))
|
||||
fastAdapter.onBindViewHolderListener = (object : OnBindViewHolderListenerImpl<CategoryItem>() {
|
||||
itemAdapter.set(listOf(headerItem) + items.map(::CategoryItem))
|
||||
fastAdapter.onBindViewHolderListener =
|
||||
(object : OnBindViewHolderListenerImpl<CategoryItem>() {
|
||||
override fun onBindViewHolder(
|
||||
viewHolder: ViewHolder,
|
||||
position: Int,
|
||||
@ -40,26 +48,42 @@ class CategoryRecyclerView @JvmOverloads constructor(
|
||||
) {
|
||||
super.onBindViewHolder(viewHolder, position, payloads)
|
||||
(viewHolder as? CategoryItem.ViewHolder)?.categoryTitle?.isSelected =
|
||||
selectedCategory == position
|
||||
selectedCategory + 1 == position
|
||||
}
|
||||
})
|
||||
fastAdapter.onClickListener = { _, _, item, _ ->
|
||||
if (item.category.id != -1)
|
||||
onCategoryClicked(item.category.order)
|
||||
true
|
||||
}
|
||||
fastAdapter.addEventHook(object : CustomEventHook<CategoryItem>() {
|
||||
override fun onBind(viewHolder: ViewHolder): View? {
|
||||
return if (viewHolder is CategoryItem.ShowAllViewHolder) {
|
||||
viewHolder.checkbox
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
override fun attachEvent(view: View, viewHolder: ViewHolder) {
|
||||
(view as? CheckBox)?.setOnCheckedChangeListener { _, isChecked ->
|
||||
onShowAllClicked(isChecked)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun setCategories(selected: Int) {
|
||||
selectedCategory = selected
|
||||
for (i in 0..manager.itemCount) {
|
||||
(findViewHolderForAdapterPosition(i) as? CategoryItem.ViewHolder)?.categoryTitle?.isSelected =
|
||||
selectedCategory == i
|
||||
selectedCategory + 1 == i
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMeasure(widthSpec: Int, heightSpec: Int) {
|
||||
val recyclerView = (parent.parent as ViewGroup).findViewById<RecyclerView>(R.id.recycler)
|
||||
val top = recyclerView.marginTop
|
||||
val top = recyclerView.paddingTop
|
||||
val bottom = recyclerView.marginBottom
|
||||
val parent = recyclerView.measuredHeight - top - bottom
|
||||
val heightS = if (parent > 0)
|
||||
|
@ -96,7 +96,7 @@ fun Controller.scrollViewWith(
|
||||
elevate = el
|
||||
if (liftOnScroll != null) {
|
||||
liftOnScroll.invoke(el)
|
||||
} else {
|
||||
} else if (recycler.translationY == 0f) {
|
||||
elevationAnim?.cancel()
|
||||
elevationAnim = ValueAnimator.ofFloat(
|
||||
activity!!.appbar.elevation, if (el) 15f else 0f
|
||||
@ -158,7 +158,9 @@ fun Controller.scrollViewWith(
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
super.onScrolled(recyclerView, dx, dy)
|
||||
if (router?.backstack?.lastOrNull()
|
||||
?.controller() == this@scrollViewWith && statusBarHeight > -1 && activity != null && activity!!.appbar.height > 0
|
||||
?.controller() == this@scrollViewWith && statusBarHeight > -1 &&
|
||||
activity != null && activity!!.appbar.height > 0 &&
|
||||
recycler.translationY == 0f
|
||||
) {
|
||||
if (!recycler.canScrollVertically(-1)) {
|
||||
val shortAnimationDuration = resources?.getInteger(
|
||||
@ -185,7 +187,9 @@ fun Controller.scrollViewWith(
|
||||
super.onScrollStateChanged(recyclerView, newState)
|
||||
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
|
||||
if (router?.backstack?.lastOrNull()
|
||||
?.controller() == this@scrollViewWith && statusBarHeight > -1 && activity != null && activity!!.appbar.height > 0
|
||||
?.controller() == this@scrollViewWith && statusBarHeight > -1 &&
|
||||
activity != null && activity!!.appbar.height > 0 &&
|
||||
recycler.translationY == 0f
|
||||
) {
|
||||
val halfWay = abs((-activity!!.appbar.height.toFloat()) / 2)
|
||||
val shortAnimationDuration = resources?.getInteger(
|
||||
|
@ -8,9 +8,9 @@
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress"
|
||||
android:layout_gravity="center"
|
||||
android:layout_width="75dp"
|
||||
android:layout_height="75dp"/>
|
||||
android:layout_height="75dp"
|
||||
android:layout_gravity="center" />
|
||||
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
android:id="@+id/swipe_refresh"
|
||||
@ -22,34 +22,39 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/category_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_marginTop="?actionBarSize"
|
||||
android:orientation="vertical"
|
||||
android:gravity="top"
|
||||
android:layout_height="wrap_content" >
|
||||
<com.google.android.material.checkbox.MaterialCheckBox
|
||||
android:id="@+id/show_all"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/show_all_categories"/>
|
||||
android:layout_marginTop="?actionBarSize"
|
||||
android:orientation="vertical">
|
||||
|
||||
<eu.kanade.tachiyomi.ui.library.category.CategoryRecyclerView
|
||||
android:id="@+id/category_recycler"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
android:layout_height="8dp"
|
||||
android:alpha="0.1"
|
||||
android:background="@drawable/shape_gradient_top_shadow"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<include layout="@layout/library_grid_recycler" />
|
||||
|
||||
<View
|
||||
android:id="@+id/recycler_cover"
|
||||
android:layout_marginTop="?actionBarSize"
|
||||
android:alpha="0"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:alpha="0"
|
||||
android:background="?android:colorBackground" />
|
||||
</FrameLayout>
|
||||
|
||||
@ -61,16 +66,16 @@
|
||||
|
||||
<com.reddit.indicatorfastscroll.FastScrollerView
|
||||
android:id="@+id/fast_scroller"
|
||||
android:textColor="?android:attr/textColorPrimaryInverse"
|
||||
android:layout_width="25dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:elevation="10dp"
|
||||
android:layout_gravity="end"
|
||||
android:background="@drawable/fast_scroll_background"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:elevation="10dp"
|
||||
android:paddingStart="3dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingEnd="0dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:textColor="?android:attr/textColorPrimaryInverse"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
@ -80,14 +85,14 @@
|
||||
android:id="@+id/text_view_m"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:alpha="0"
|
||||
tools:alpha="1"
|
||||
android:layout_marginEnd="50dp"
|
||||
android:alpha="0"
|
||||
android:background="@drawable/round_textview_background"
|
||||
android:padding="10dp"
|
||||
android:textColor="@android:color/white"
|
||||
app:layout_constraintEnd_toStartOf="@id/fast_scroller"
|
||||
app:layout_constraintTop_toTopOf="@id/fast_scroller"
|
||||
tools:alpha="1"
|
||||
tools:text="Category" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user