diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/util/PagerNestedScrollHelper.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/util/PagerNestedScrollHelper.kt new file mode 100644 index 000000000..e931ef3a9 --- /dev/null +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/util/PagerNestedScrollHelper.kt @@ -0,0 +1,50 @@ +package org.koitharu.kotatsu.core.ui.util + +import android.view.View +import androidx.coordinatorlayout.widget.CoordinatorLayout +import androidx.core.view.ancestors +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.Lifecycle.State.RESUMED +import androidx.lifecycle.LifecycleOwner +import androidx.recyclerview.widget.RecyclerView +import com.google.android.material.bottomsheet.BottomSheetBehavior + +class PagerNestedScrollHelper( + private val recyclerView: RecyclerView, +) : DefaultLifecycleObserver { + + fun bind(lifecycleOwner: LifecycleOwner) { + lifecycleOwner.lifecycle.addObserver(this) + recyclerView.isNestedScrollingEnabled = lifecycleOwner.lifecycle.currentState.isAtLeast(RESUMED) + } + + override fun onPause(owner: LifecycleOwner) { + recyclerView.isNestedScrollingEnabled = false + invalidateBottomSheetScrollTarget() + } + + override fun onResume(owner: LifecycleOwner) { + recyclerView.isNestedScrollingEnabled = true + } + + override fun onDestroy(owner: LifecycleOwner) { + owner.lifecycle.removeObserver(this) + } + + /** + * Here we need to invalidate the `nestedScrollingChildRef` of the [BottomSheetBehavior] + */ + private fun invalidateBottomSheetScrollTarget() { + var handleCoordinator = false + for (parent in recyclerView.ancestors) { + if (handleCoordinator && parent is CoordinatorLayout) { + parent.requestLayout() + break + } + val lp = (parent as? View)?.layoutParams ?: continue + if (lp is CoordinatorLayout.LayoutParams && lp.behavior is BottomSheetBehavior<*>) { + handleCoordinator = true + } + } + } +} diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsActivity.kt index 0bb14f678..03a782490 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsActivity.kt @@ -156,7 +156,6 @@ class DetailsActivity : viewBinding.chipsTags.onChipClickListener = this TitleScrollCoordinator(viewBinding.textViewTitle).attach(viewBinding.scrollView) viewBinding.containerBottomSheet?.let { BottomSheetBehavior.from(it) }?.let { behavior -> - behavior.addBottomSheetCallback(BottomSheetNoHalfExpandedCallback()) onBackPressedDispatcher.addCallback(BottomSheetClollapseCallback(behavior)) } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/ChaptersPagesSheet.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/ChaptersPagesSheet.kt index 8e86ff6a6..c360aadac 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/ChaptersPagesSheet.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/ChaptersPagesSheet.kt @@ -25,6 +25,7 @@ import org.koitharu.kotatsu.core.util.ext.doOnPageChanged import org.koitharu.kotatsu.core.util.ext.menuView import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observeEvent +import org.koitharu.kotatsu.core.util.ext.recyclerView import org.koitharu.kotatsu.core.util.ext.setTabsEnabled import org.koitharu.kotatsu.core.util.ext.showDistinct import org.koitharu.kotatsu.core.util.ext.withArgs @@ -56,6 +57,7 @@ class ChaptersPagesSheet : BaseAdaptiveSheet(), Actio defaultTab = (defaultTab - 1).coerceAtLeast(TAB_CHAPTERS) } binding.pager.offscreenPageLimit = adapter.itemCount + binding.pager.recyclerView?.isNestedScrollingEnabled = false binding.pager.adapter = adapter binding.pager.doOnPageChanged(::onPageChanged) TabLayoutMediator(binding.tabs, binding.pager, adapter).attach() diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/bookmarks/MangaBookmarksFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/bookmarks/MangaBookmarksFragment.kt index d52f9c719..bae5c7e1e 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/bookmarks/MangaBookmarksFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/bookmarks/MangaBookmarksFragment.kt @@ -15,6 +15,7 @@ import org.koitharu.kotatsu.bookmarks.ui.sheet.BookmarksAdapter import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.ui.BaseFragment import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener +import org.koitharu.kotatsu.core.ui.util.PagerNestedScrollHelper import org.koitharu.kotatsu.core.util.ext.dismissParentDialog import org.koitharu.kotatsu.core.util.ext.findParentCallback import org.koitharu.kotatsu.core.util.ext.observe @@ -69,6 +70,8 @@ class MangaBookmarksFragment : BaseFragment(), viewModel.gridScale.observe(viewLifecycleOwner, ::onGridScaleChanged) // before rv initialization with(binding.recyclerView) { addItemDecoration(TypedListSpacingDecoration(context, false)) + setHasFixedSize(true) + PagerNestedScrollHelper(this).bind(viewLifecycleOwner) adapter = bookmarksAdapter addOnLayoutChangeListener(spanResolver) (layoutManager as GridLayoutManager).let { @@ -76,7 +79,7 @@ class MangaBookmarksFragment : BaseFragment(), it.spanCount = checkNotNull(spanResolver).spanCount } } - viewModel.content.observe(viewLifecycleOwner, checkNotNull(bookmarksAdapter)) + viewModel.content.observe(viewLifecycleOwner) { bookmarksAdapter?.setItems(it, listCommitCallback) } } override fun onDestroyView() { @@ -86,17 +89,6 @@ class MangaBookmarksFragment : BaseFragment(), super.onDestroyView() } - override fun onPause() { - // required for BottomSheetBehavior - requireViewBinding().recyclerView.isNestedScrollingEnabled = false - super.onPause() - } - - override fun onResume() { - requireViewBinding().recyclerView.isNestedScrollingEnabled = true - super.onResume() - } - override fun onWindowInsetsChanged(insets: Insets) = Unit override fun onItemClick(item: Bookmark, view: View) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/chapters/ChaptersFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/chapters/ChaptersFragment.kt index 072725323..3966c7b0d 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/chapters/ChaptersFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/chapters/ChaptersFragment.kt @@ -22,6 +22,7 @@ import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.ui.BaseFragment import org.koitharu.kotatsu.core.ui.list.ListSelectionController import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener +import org.koitharu.kotatsu.core.ui.util.PagerNestedScrollHelper import org.koitharu.kotatsu.core.util.RecyclerViewScrollCallback import org.koitharu.kotatsu.core.util.ext.dismissParentDialog import org.koitharu.kotatsu.core.util.ext.findAppCompatDelegate @@ -80,7 +81,7 @@ class ChaptersFragment : addItemDecoration(TypedListSpacingDecoration(context, true)) checkNotNull(selectionController).attachToRecyclerView(this) setHasFixedSize(true) - isNestedScrollingEnabled = false + PagerNestedScrollHelper(this).bind(viewLifecycleOwner) adapter = chaptersAdapter ChapterGridSpanHelper.attach(this) } @@ -101,17 +102,6 @@ class ChaptersFragment : super.onDestroyView() } - override fun onPause() { - // required for BottomSheetBehavior - requireViewBinding().recyclerViewChapters.isNestedScrollingEnabled = false - super.onPause() - } - - override fun onResume() { - requireViewBinding().recyclerViewChapters.isNestedScrollingEnabled = true - super.onResume() - } - override fun onItemClick(item: ChapterListItem, view: View) { if (selectionController?.onItemClick(item.chapter.id) == true) { return diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/pages/PagesFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/pages/PagesFragment.kt index 453f269c4..49acedf7b 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/pages/PagesFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/pages/PagesFragment.kt @@ -22,6 +22,7 @@ import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.ui.BaseFragment import org.koitharu.kotatsu.core.ui.list.BoundsScrollListener import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener +import org.koitharu.kotatsu.core.ui.util.PagerNestedScrollHelper import org.koitharu.kotatsu.core.util.RecyclerViewScrollCallback import org.koitharu.kotatsu.core.util.ext.dismissParentDialog import org.koitharu.kotatsu.core.util.ext.findParentCallback @@ -93,7 +94,7 @@ class PagesFragment : addItemDecoration(TypedListSpacingDecoration(context, false)) adapter = thumbnailsAdapter setHasFixedSize(true) - isNestedScrollingEnabled = false + PagerNestedScrollHelper(this).bind(viewLifecycleOwner) addOnLayoutChangeListener(spanResolver) addOnScrollListener(ScrollListener().also { scrollListener = it }) (layoutManager as GridLayoutManager).let { @@ -117,17 +118,6 @@ class PagesFragment : super.onDestroyView() } - override fun onPause() { - // required for BottomSheetBehavior - requireViewBinding().recyclerView.isNestedScrollingEnabled = false - super.onPause() - } - - override fun onResume() { - requireViewBinding().recyclerView.isNestedScrollingEnabled = true - super.onResume() - } - override fun onWindowInsetsChanged(insets: Insets) = Unit override fun onItemClick(item: PageThumbnail, view: View) { diff --git a/app/src/main/res/layout/activity_details.xml b/app/src/main/res/layout/activity_details.xml index e40706906..e0b5d010a 100644 --- a/app/src/main/res/layout/activity_details.xml +++ b/app/src/main/res/layout/activity_details.xml @@ -406,7 +406,7 @@ android:nestedScrollingEnabled="false" android:outlineProvider="background" app:behavior_fitToContents="false" - app:behavior_halfExpandedRatio="0.00001" + app:behavior_halfExpandedRatio="0.8" app:behavior_hideable="false" app:behavior_peekHeight="@dimen/details_bs_peek_height" app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"