mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-30 22:07:57 +01:00 
			
		
		
		
	Toolbar and bottom nav scroll snap (#5915)
This commit is contained in:
		| @@ -5,10 +5,12 @@ import android.content.Context | ||||
| import android.util.AttributeSet | ||||
| import android.widget.TextView | ||||
| import androidx.annotation.FloatRange | ||||
| import androidx.coordinatorlayout.widget.CoordinatorLayout | ||||
| import androidx.lifecycle.coroutineScope | ||||
| import androidx.lifecycle.findViewTreeLifecycleOwner | ||||
| import com.google.android.material.animation.AnimationUtils | ||||
| import com.google.android.material.appbar.AppBarLayout | ||||
| import com.google.android.material.appbar.HideToolbarOnScrollBehavior | ||||
| import com.google.android.material.appbar.MaterialToolbar | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.util.view.findChild | ||||
| @@ -51,6 +53,8 @@ class ElevationAppBarLayout @JvmOverloads constructor( | ||||
|             } | ||||
|         } | ||||
|  | ||||
|     override fun getBehavior(): CoordinatorLayout.Behavior<AppBarLayout> = HideToolbarOnScrollBehavior() | ||||
|  | ||||
|     /** | ||||
|      * Disabled. Lift on scroll is handled manually with [TachiyomiCoordinatorLayout] | ||||
|      */ | ||||
|   | ||||
| @@ -1,11 +1,19 @@ | ||||
| package eu.kanade.tachiyomi.widget | ||||
|  | ||||
| import android.animation.ValueAnimator | ||||
| import android.content.Context | ||||
| import android.util.AttributeSet | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import android.view.animation.DecelerateInterpolator | ||||
| import androidx.appcompat.widget.Toolbar | ||||
| import androidx.coordinatorlayout.widget.CoordinatorLayout | ||||
| import androidx.core.view.ViewCompat | ||||
| import com.google.android.material.appbar.AppBarLayout | ||||
| import com.google.android.material.bottomnavigation.BottomNavigationView | ||||
| import eu.kanade.tachiyomi.util.system.animatorDurationScale | ||||
| import eu.kanade.tachiyomi.util.view.findChild | ||||
| import kotlin.math.roundToLong | ||||
|  | ||||
| /** | ||||
|  * Hide behavior similar to app bar for [BottomNavigationView] | ||||
| @@ -15,6 +23,31 @@ class HideBottomNavigationOnScrollBehavior @JvmOverloads constructor( | ||||
|     attrs: AttributeSet? = null | ||||
| ) : CoordinatorLayout.Behavior<BottomNavigationView>(context, attrs) { | ||||
|  | ||||
|     @ViewCompat.NestedScrollType | ||||
|     private var lastStartedType: Int = 0 | ||||
|  | ||||
|     private var offsetAnimator: ValueAnimator? = null | ||||
|  | ||||
|     private var dyRatio = 1F | ||||
|  | ||||
|     override fun layoutDependsOn(parent: CoordinatorLayout, child: BottomNavigationView, dependency: View): Boolean { | ||||
|         return dependency is AppBarLayout | ||||
|     } | ||||
|  | ||||
|     override fun onDependentViewChanged( | ||||
|         parent: CoordinatorLayout, | ||||
|         child: BottomNavigationView, | ||||
|         dependency: View | ||||
|     ): Boolean { | ||||
|         val toolbarSize = (dependency as ViewGroup).findChild<Toolbar>()?.height ?: 0 | ||||
|         dyRatio = if (toolbarSize > 0) { | ||||
|             child.height.toFloat() / toolbarSize | ||||
|         } else { | ||||
|             1F | ||||
|         } | ||||
|         return false | ||||
|     } | ||||
|  | ||||
|     override fun onStartNestedScroll( | ||||
|         coordinatorLayout: CoordinatorLayout, | ||||
|         child: BottomNavigationView, | ||||
| @@ -23,7 +56,12 @@ class HideBottomNavigationOnScrollBehavior @JvmOverloads constructor( | ||||
|         axes: Int, | ||||
|         type: Int | ||||
|     ): Boolean { | ||||
|         return axes == ViewCompat.SCROLL_AXIS_VERTICAL | ||||
|         if (axes != ViewCompat.SCROLL_AXIS_VERTICAL) { | ||||
|             return false | ||||
|         } | ||||
|         lastStartedType = type | ||||
|         offsetAnimator?.cancel() | ||||
|         return true | ||||
|     } | ||||
|  | ||||
|     override fun onNestedPreScroll( | ||||
| @@ -36,6 +74,33 @@ class HideBottomNavigationOnScrollBehavior @JvmOverloads constructor( | ||||
|         type: Int | ||||
|     ) { | ||||
|         super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type) | ||||
|         child.translationY = (child.translationY + dy).coerceIn(0F, child.height.toFloat()) | ||||
|         child.translationY = (child.translationY + (dy * dyRatio)).coerceIn(0F, child.height.toFloat()) | ||||
|     } | ||||
|  | ||||
|     override fun onStopNestedScroll( | ||||
|         coordinatorLayout: CoordinatorLayout, | ||||
|         child: BottomNavigationView, | ||||
|         target: View, | ||||
|         type: Int | ||||
|     ) { | ||||
|         if (lastStartedType == ViewCompat.TYPE_TOUCH || type == ViewCompat.TYPE_NON_TOUCH) { | ||||
|             animateBottomNavigationVisibility(child, child.translationY < child.height / 2) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private fun animateBottomNavigationVisibility(child: BottomNavigationView, isVisible: Boolean) { | ||||
|         offsetAnimator?.cancel() | ||||
|         offsetAnimator = ValueAnimator().apply { | ||||
|             interpolator = DecelerateInterpolator() | ||||
|             duration = (150 * child.context.animatorDurationScale).roundToLong() | ||||
|             addUpdateListener { | ||||
|                 child.translationY = it.animatedValue as Float | ||||
|             } | ||||
|         } | ||||
|         offsetAnimator?.setFloatValues( | ||||
|             child.translationY, | ||||
|             if (isVisible) 0F else child.height.toFloat() | ||||
|         ) | ||||
|         offsetAnimator?.start() | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user