From ff2a4e69526a2edfa5f3bd7570c09204e5ebb9f9 Mon Sep 17 00:00:00 2001 From: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com> Date: Sat, 31 Jul 2021 23:05:24 +0700 Subject: [PATCH] Change BottomNavigationView behavior (#5603) Similar to app bar's scroll behavior --- .../tachiyomi/ui/library/LibraryController.kt | 4 +- .../kanade/tachiyomi/ui/main/MainActivity.kt | 45 ++++++------------- .../ui/recent/updates/UpdatesController.kt | 4 +- .../HideBottomNavigationOnScrollBehavior.kt | 41 +++++++++++++++++ 4 files changed, 59 insertions(+), 35 deletions(-) create mode 100644 app/src/main/java/eu/kanade/tachiyomi/widget/HideBottomNavigationOnScrollBehavior.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt index 312437477f..d89426f913 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt @@ -377,7 +377,7 @@ class LibraryController( actionMode!!, R.menu.library_selection ) { onActionItemClicked(it!!) } - (activity as? MainActivity)?.showBottomNav(visible = false, collapse = true) + (activity as? MainActivity)?.showBottomNav(visible = false, expand = true) } } @@ -486,7 +486,7 @@ class LibraryController( selectionRelay.call(LibrarySelectionEvent.Cleared()) binding.actionToolbar.hide() - (activity as? MainActivity)?.showBottomNav(visible = true, collapse = true) + (activity as? MainActivity)?.showBottomNav(visible = true, expand = true) actionMode = null } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt index 7c5931c1fb..ee7eda7ae1 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt @@ -28,7 +28,6 @@ import com.bluelinelabs.conductor.Controller import com.bluelinelabs.conductor.ControllerChangeHandler import com.bluelinelabs.conductor.Router import com.google.android.material.appbar.AppBarLayout -import com.google.android.material.behavior.HideBottomViewOnScrollBehavior import com.google.android.material.navigation.NavigationBarView import dev.chrisbanes.insetter.applyInsetter import eu.kanade.tachiyomi.BuildConfig @@ -61,6 +60,7 @@ import eu.kanade.tachiyomi.util.lang.launchUI import eu.kanade.tachiyomi.util.system.dpToPx import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.view.setNavigationBarTransparentCompat +import eu.kanade.tachiyomi.widget.HideBottomNavigationOnScrollBehavior import kotlinx.coroutines.delay import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.launchIn @@ -142,15 +142,6 @@ class MainActivity : BaseViewBindingActivity() { if (binding.bottomNav != null) { bottomNavAnimator = ViewHeightAnimator(binding.bottomNav!!) - // If bottom nav is hidden, make it visible again when the app bar is expanded - binding.appbar.addOnOffsetChangedListener( - AppBarLayout.OnOffsetChangedListener { _, verticalOffset -> - if (verticalOffset == 0) { - showNav(visible = true) - } - } - ) - // Set behavior of bottom nav preferences.hideBottomBarOnScroll() .asImmediateFlow { setBottomNavBehaviorOnScroll() } @@ -502,11 +493,11 @@ class MainActivity : BaseViewBindingActivity() { binding.appbar.setExpanded(true) if ((from == null || from is RootController) && to !is RootController) { - showNav(visible = false, collapse = true) + showNav(visible = false, expand = true) } if (to is RootController) { // Always show bottom nav again when returning to a RootController - showNav(visible = true, collapse = from !is RootController) + showNav(visible = true, expand = from !is RootController) } if (from is TabbedController) { @@ -542,29 +533,20 @@ class MainActivity : BaseViewBindingActivity() { } } - private fun showNav(visible: Boolean, collapse: Boolean = false) { - showBottomNav(visible, collapse) + private fun showNav(visible: Boolean, expand: Boolean = false) { + showBottomNav(visible, expand) showSideNav(visible) } // Also used from some controllers to swap bottom nav with action toolbar - fun showBottomNav(visible: Boolean, collapse: Boolean = false) { - binding.bottomNav?.let { - val layoutParams = it.layoutParams as CoordinatorLayout.LayoutParams - val bottomViewNavigationBehavior = - layoutParams.behavior as? HideBottomViewOnScrollBehavior - if (visible) { - if (collapse) { - bottomNavAnimator?.expand() - } - bottomViewNavigationBehavior?.slideUp(it) - } else { - if (collapse) { - bottomNavAnimator?.collapse() - } - - bottomViewNavigationBehavior?.slideDown(it) + fun showBottomNav(visible: Boolean, expand: Boolean = false) { + if (visible) { + binding.bottomNav?.translationY = 0F + if (expand) { + bottomNavAnimator?.expand() } + } else { + bottomNavAnimator?.collapse() } } @@ -597,10 +579,11 @@ class MainActivity : BaseViewBindingActivity() { binding.bottomNav?.updateLayoutParams { behavior = when { - preferences.hideBottomBarOnScroll().get() -> HideBottomViewOnScrollBehavior() + preferences.hideBottomBarOnScroll().get() -> HideBottomNavigationOnScrollBehavior() else -> null } } + binding.bottomNav?.translationY = 0F } private val nav: NavigationBarView diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt index 2a917c0b6f..aa8827494b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt @@ -183,7 +183,7 @@ class UpdatesController : actionMode!!, R.menu.updates_chapter_selection ) { onActionItemClicked(it!!) } - (activity as? MainActivity)?.showBottomNav(visible = false, collapse = true) + (activity as? MainActivity)?.showBottomNav(visible = false, expand = true) } toggleSelection(position) @@ -389,7 +389,7 @@ class UpdatesController : adapter?.clearSelection() binding.actionToolbar.hide() - (activity as? MainActivity)?.showBottomNav(visible = true, collapse = true) + (activity as? MainActivity)?.showBottomNav(visible = true, expand = true) actionMode = null } diff --git a/app/src/main/java/eu/kanade/tachiyomi/widget/HideBottomNavigationOnScrollBehavior.kt b/app/src/main/java/eu/kanade/tachiyomi/widget/HideBottomNavigationOnScrollBehavior.kt new file mode 100644 index 0000000000..27a1d7b9df --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/widget/HideBottomNavigationOnScrollBehavior.kt @@ -0,0 +1,41 @@ +package eu.kanade.tachiyomi.widget + +import android.content.Context +import android.util.AttributeSet +import android.view.View +import androidx.coordinatorlayout.widget.CoordinatorLayout +import androidx.core.view.ViewCompat +import com.google.android.material.bottomnavigation.BottomNavigationView + +/** + * Hide behavior similar to app bar for [BottomNavigationView] + */ +class HideBottomNavigationOnScrollBehavior @JvmOverloads constructor( + context: Context? = null, + attrs: AttributeSet? = null +) : CoordinatorLayout.Behavior(context, attrs) { + + override fun onStartNestedScroll( + coordinatorLayout: CoordinatorLayout, + child: BottomNavigationView, + directTargetChild: View, + target: View, + axes: Int, + type: Int + ): Boolean { + return axes == ViewCompat.SCROLL_AXIS_VERTICAL + } + + override fun onNestedPreScroll( + coordinatorLayout: CoordinatorLayout, + child: BottomNavigationView, + target: View, + dx: Int, + dy: Int, + consumed: IntArray, + type: Int + ) { + super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type) + child.translationY = (child.translationY + dy).coerceIn(0F, child.height.toFloat()) + } +}