Change BottomNavigationView behavior (#5603)

Similar to app bar's scroll behavior
This commit is contained in:
Ivan Iskandar 2021-07-31 23:05:24 +07:00 committed by GitHub
parent 7660751f7f
commit ff2a4e6952
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 59 additions and 35 deletions

View file

@ -377,7 +377,7 @@ class LibraryController(
actionMode!!, actionMode!!,
R.menu.library_selection R.menu.library_selection
) { onActionItemClicked(it!!) } ) { 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()) selectionRelay.call(LibrarySelectionEvent.Cleared())
binding.actionToolbar.hide() binding.actionToolbar.hide()
(activity as? MainActivity)?.showBottomNav(visible = true, collapse = true) (activity as? MainActivity)?.showBottomNav(visible = true, expand = true)
actionMode = null actionMode = null
} }

View file

@ -28,7 +28,6 @@ import com.bluelinelabs.conductor.Controller
import com.bluelinelabs.conductor.ControllerChangeHandler import com.bluelinelabs.conductor.ControllerChangeHandler
import com.bluelinelabs.conductor.Router import com.bluelinelabs.conductor.Router
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.behavior.HideBottomViewOnScrollBehavior
import com.google.android.material.navigation.NavigationBarView import com.google.android.material.navigation.NavigationBarView
import dev.chrisbanes.insetter.applyInsetter import dev.chrisbanes.insetter.applyInsetter
import eu.kanade.tachiyomi.BuildConfig 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.dpToPx
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.setNavigationBarTransparentCompat import eu.kanade.tachiyomi.util.view.setNavigationBarTransparentCompat
import eu.kanade.tachiyomi.widget.HideBottomNavigationOnScrollBehavior
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
@ -142,15 +142,6 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
if (binding.bottomNav != null) { if (binding.bottomNav != null) {
bottomNavAnimator = ViewHeightAnimator(binding.bottomNav!!) 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 // Set behavior of bottom nav
preferences.hideBottomBarOnScroll() preferences.hideBottomBarOnScroll()
.asImmediateFlow { setBottomNavBehaviorOnScroll() } .asImmediateFlow { setBottomNavBehaviorOnScroll() }
@ -502,11 +493,11 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
binding.appbar.setExpanded(true) binding.appbar.setExpanded(true)
if ((from == null || from is RootController) && to !is RootController) { if ((from == null || from is RootController) && to !is RootController) {
showNav(visible = false, collapse = true) showNav(visible = false, expand = true)
} }
if (to is RootController) { if (to is RootController) {
// Always show bottom nav again when returning to a 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) { if (from is TabbedController) {
@ -542,30 +533,21 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
} }
} }
private fun showNav(visible: Boolean, collapse: Boolean = false) { private fun showNav(visible: Boolean, expand: Boolean = false) {
showBottomNav(visible, collapse) showBottomNav(visible, expand)
showSideNav(visible) showSideNav(visible)
} }
// Also used from some controllers to swap bottom nav with action toolbar // Also used from some controllers to swap bottom nav with action toolbar
fun showBottomNav(visible: Boolean, collapse: Boolean = false) { fun showBottomNav(visible: Boolean, expand: Boolean = false) {
binding.bottomNav?.let {
val layoutParams = it.layoutParams as CoordinatorLayout.LayoutParams
val bottomViewNavigationBehavior =
layoutParams.behavior as? HideBottomViewOnScrollBehavior
if (visible) { if (visible) {
if (collapse) { binding.bottomNav?.translationY = 0F
if (expand) {
bottomNavAnimator?.expand() bottomNavAnimator?.expand()
} }
bottomViewNavigationBehavior?.slideUp(it)
} else { } else {
if (collapse) {
bottomNavAnimator?.collapse() bottomNavAnimator?.collapse()
} }
bottomViewNavigationBehavior?.slideDown(it)
}
}
} }
private fun showSideNav(visible: Boolean) { private fun showSideNav(visible: Boolean) {
@ -597,10 +579,11 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
binding.bottomNav?.updateLayoutParams<CoordinatorLayout.LayoutParams> { binding.bottomNav?.updateLayoutParams<CoordinatorLayout.LayoutParams> {
behavior = when { behavior = when {
preferences.hideBottomBarOnScroll().get() -> HideBottomViewOnScrollBehavior<View>() preferences.hideBottomBarOnScroll().get() -> HideBottomNavigationOnScrollBehavior()
else -> null else -> null
} }
} }
binding.bottomNav?.translationY = 0F
} }
private val nav: NavigationBarView private val nav: NavigationBarView

View file

@ -183,7 +183,7 @@ class UpdatesController :
actionMode!!, actionMode!!,
R.menu.updates_chapter_selection R.menu.updates_chapter_selection
) { onActionItemClicked(it!!) } ) { onActionItemClicked(it!!) }
(activity as? MainActivity)?.showBottomNav(visible = false, collapse = true) (activity as? MainActivity)?.showBottomNav(visible = false, expand = true)
} }
toggleSelection(position) toggleSelection(position)
@ -389,7 +389,7 @@ class UpdatesController :
adapter?.clearSelection() adapter?.clearSelection()
binding.actionToolbar.hide() binding.actionToolbar.hide()
(activity as? MainActivity)?.showBottomNav(visible = true, collapse = true) (activity as? MainActivity)?.showBottomNav(visible = true, expand = true)
actionMode = null actionMode = null
} }

View file

@ -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<BottomNavigationView>(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())
}
}