mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 08:08:55 +01:00 
			
		
		
		
	Change BottomNavigationView behavior (#5603)
Similar to app bar's scroll behavior
This commit is contained in:
		@@ -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
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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<MainActivityBinding>() {
 | 
			
		||||
        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<MainActivityBinding>() {
 | 
			
		||||
        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<MainActivityBinding>() {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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<MainActivityBinding>() {
 | 
			
		||||
 | 
			
		||||
        binding.bottomNav?.updateLayoutParams<CoordinatorLayout.LayoutParams> {
 | 
			
		||||
            behavior = when {
 | 
			
		||||
                preferences.hideBottomBarOnScroll().get() -> HideBottomViewOnScrollBehavior<View>()
 | 
			
		||||
                preferences.hideBottomBarOnScroll().get() -> HideBottomNavigationOnScrollBehavior()
 | 
			
		||||
                else -> null
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        binding.bottomNav?.translationY = 0F
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private val nav: NavigationBarView
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user