diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/BottomSheetHeaderBar.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/BottomSheetHeaderBar.kt index 19757304e..cd60b79f8 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/BottomSheetHeaderBar.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/BottomSheetHeaderBar.kt @@ -26,6 +26,8 @@ import org.koitharu.kotatsu.utils.ext.getAnimationDuration import org.koitharu.kotatsu.utils.ext.getThemeDrawable import org.koitharu.kotatsu.utils.ext.parents +private const val THROTTLE_DELAY = 200L + class BottomSheetHeaderBar @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, @@ -35,6 +37,7 @@ class BottomSheetHeaderBar @JvmOverloads constructor( private val binding = LayoutSheetHeaderBinding.inflate(LayoutInflater.from(context), this) private val closeDrawable = context.getThemeDrawable(materialR.attr.actionModeCloseDrawable) private val bottomSheetCallback = Callback() + private val adjustStateRunnable = Runnable { adjustState() } private var bottomSheetBehavior: BottomSheetBehavior<*>? = null private val locationBuffer = IntArray(2) private val expansionListeners = LinkedList() @@ -43,6 +46,8 @@ class BottomSheetHeaderBar @JvmOverloads constructor( private val maxHandleHeight = context.resources.getDimensionPixelSize(R.dimen.bottom_sheet_handle_size_max) private var isLayoutSuppressedCompat = false private var isLayoutCalledWhileSuppressed = false + private var isBsExpanded = false + private var stateAdjustedAt = 0L @Deprecated("") val toolbar: MaterialToolbar @@ -173,16 +178,11 @@ class BottomSheetHeaderBar @JvmOverloads constructor( } private fun onBottomSheetStateChanged(newState: Int) { - val isExpanded = newState == BottomSheetBehavior.STATE_EXPANDED && isOnTopOfScreen() - if (isExpanded == binding.dragHandle.isGone) { - return + val expanded = newState == BottomSheetBehavior.STATE_EXPANDED && isOnTopOfScreen() + if (isBsExpanded != expanded) { + isBsExpanded = expanded + postAdjustState() } - suppressLayoutCompat(true) - binding.toolbar.navigationIcon = (if (isExpanded) closeDrawable else null) - binding.dragHandle.isGone = isExpanded - expansionListeners.forEach { it.onExpansionStateChanged(this, isExpanded) } - dispatchInsets(ViewCompat.getRootWindowInsets(this)) - suppressLayoutCompat(false) } private fun suppressLayoutCompat(suppress: Boolean) { @@ -262,6 +262,26 @@ class BottomSheetHeaderBar @JvmOverloads constructor( } } + private fun postAdjustState() { + removeCallbacks(adjustStateRunnable) + val now = System.currentTimeMillis() + if (stateAdjustedAt + THROTTLE_DELAY < now) { + adjustState() + } else { + postDelayed(adjustStateRunnable, THROTTLE_DELAY) + } + } + + private fun adjustState() { + suppressLayoutCompat(true) + binding.toolbar.navigationIcon = (if (isBsExpanded) closeDrawable else null) + binding.dragHandle.isGone = isBsExpanded + expansionListeners.forEach { it.onExpansionStateChanged(this, isBsExpanded) } + dispatchInsets(ViewCompat.getRootWindowInsets(this)) + stateAdjustedAt = System.currentTimeMillis() + suppressLayoutCompat(false) + } + private inner class Callback : BottomSheetBehavior.BottomSheetCallback(), View.OnClickListener { override fun onStateChanged(bottomSheet: View, newState: Int) { diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterAdapter.kt index 19b3f11f7..6b1fe569f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterAdapter.kt @@ -1,9 +1,11 @@ package org.koitharu.kotatsu.list.ui.filter +import androidx.recyclerview.widget.AsyncListDiffer.ListListener import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter class FilterAdapter( listener: OnFilterChangedListener, + listListener: ListListener, ) : AsyncListDifferDelegationAdapter( FilterDiffCallback(), filterSortDelegate(listener), @@ -11,4 +13,9 @@ class FilterAdapter( filterHeaderDelegate(), filterLoadingDelegate(), filterErrorDelegate(), -) \ No newline at end of file +) { + + init { + differ.addListListener(listListener) + } +} diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterBottomSheet.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterBottomSheet.kt index 6da92b951..e7be8c8b6 100644 --- a/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterBottomSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterBottomSheet.kt @@ -6,17 +6,21 @@ import android.os.Bundle import android.view.* import androidx.appcompat.widget.SearchView import androidx.fragment.app.FragmentManager +import androidx.recyclerview.widget.AsyncListDiffer +import androidx.recyclerview.widget.LinearLayoutManager import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseBottomSheet import org.koitharu.kotatsu.databinding.SheetFilterBinding import org.koitharu.kotatsu.remotelist.ui.RemoteListViewModel +import org.koitharu.kotatsu.utils.ext.isScrolledToTop import org.koitharu.kotatsu.utils.ext.parentFragmentViewModels class FilterBottomSheet : BaseBottomSheet(), MenuItem.OnActionExpandListener, SearchView.OnQueryTextListener, - DialogInterface.OnKeyListener { + DialogInterface.OnKeyListener, + AsyncListDiffer.ListListener { private val viewModel by parentFragmentViewModels() @@ -32,7 +36,7 @@ class FilterBottomSheet : override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - val adapter = FilterAdapter(viewModel) + val adapter = FilterAdapter(viewModel, this) binding.recyclerView.adapter = adapter viewModel.filterItems.observe(viewLifecycleOwner, adapter::setItems) initOptionsMenu() @@ -70,6 +74,12 @@ class FilterBottomSheet : return false } + override fun onCurrentListChanged(previousList: MutableList, currentList: MutableList) { + if (currentList.size > previousList.size && view != null) { + (binding.recyclerView.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(0, 0) + } + } + private fun initOptionsMenu() { binding.headerBar.toolbar.inflateMenu(R.menu.opt_filter) val searchMenuItem = binding.headerBar.toolbar.menu.findItem(R.id.action_search) diff --git a/app/src/main/res/layout/sheet_reader_config.xml b/app/src/main/res/layout/sheet_reader_config.xml index 34e0efcad..f2c24e5e7 100644 --- a/app/src/main/res/layout/sheet_reader_config.xml +++ b/app/src/main/res/layout/sheet_reader_config.xml @@ -103,7 +103,7 @@ android:text="@string/reader_mode_hint" android:textAppearance="?attr/textAppearanceBodySmall" /> - + app:drawableStartCompat="@drawable/ic_timer" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@id/slider_timer" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintWidth_default="wrap" /> + app:labelBehavior="floating" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@id/textView_timer" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintWidth_min="120dp" /> - +