Library toolbar now collaspses again

Moved the show all categories button into the recylcer
This commit is contained in:
Jay 2020-05-04 23:37:46 -04:00
parent f890f5cfff
commit ee2df0f87a
5 changed files with 135 additions and 72 deletions

View File

@ -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 {

View File

@ -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) {}
}
}

View File

@ -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,35 +38,52 @@ class CategoryRecyclerView @JvmOverloads constructor(
}
fun setCategories(items: List<Category>) {
itemAdapter.set(items.map(::CategoryItem))
fastAdapter.onBindViewHolderListener = (object : OnBindViewHolderListenerImpl<CategoryItem>() {
override fun onBindViewHolder(
viewHolder: ViewHolder,
position: Int,
payloads: List<Any>
) {
super.onBindViewHolder(viewHolder, position, payloads)
(viewHolder as? CategoryItem.ViewHolder)?.categoryTitle?.isSelected =
selectedCategory == position
}
})
itemAdapter.set(listOf(headerItem) + items.map(::CategoryItem))
fastAdapter.onBindViewHolderListener =
(object : OnBindViewHolderListenerImpl<CategoryItem>() {
override fun onBindViewHolder(
viewHolder: ViewHolder,
position: Int,
payloads: List<Any>
) {
super.onBindViewHolder(viewHolder, position, payloads)
(viewHolder as? CategoryItem.ViewHolder)?.categoryTitle?.isSelected =
selectedCategory + 1 == position
}
})
fastAdapter.onClickListener = { _, _, item, _ ->
onCategoryClicked(item.category.order)
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)

View File

@ -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(

View File

@ -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,35 +22,40 @@
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_height="wrap_content"
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: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:background="?android:colorBackground"/>
android:alpha="0"
android:background="?android:colorBackground" />
</FrameLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
@ -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>