You've already forked Magisk
mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-09-06 06:36:58 +00:00
Use standard BottomNav & Remove hide on scroll for AppBar and BottomNav
This commit is contained in:
@@ -1,127 +0,0 @@
|
||||
package com.topjohnwu.magisk.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
|
||||
import com.google.android.material.behavior.HideBottomViewOnScrollBehavior
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.core.Info
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class HideBottomViewOnScrollBehavior<V : View>(context: Context, attrs: AttributeSet) :
|
||||
HideBottomViewOnScrollBehavior<V>(), HideableBehavior<V> {
|
||||
|
||||
private var lockState: Boolean = false
|
||||
private var isLaidOut = false
|
||||
|
||||
override fun layoutDependsOn(parent: CoordinatorLayout, child: V, dependency: View) =
|
||||
super.layoutDependsOn(parent, child, dependency) or (dependency is Snackbar.SnackbarLayout)
|
||||
|
||||
override fun onLayoutChild(parent: CoordinatorLayout, child: V, layoutDirection: Int): Boolean {
|
||||
isLaidOut = true
|
||||
return super.onLayoutChild(parent, child, layoutDirection)
|
||||
}
|
||||
|
||||
override fun onDependentViewChanged(
|
||||
parent: CoordinatorLayout,
|
||||
child: V,
|
||||
dependency: View
|
||||
) = when (dependency) {
|
||||
is Snackbar.SnackbarLayout -> onDependentViewChanged(parent, child, dependency)
|
||||
else -> super.onDependentViewChanged(parent, child, dependency)
|
||||
}
|
||||
|
||||
override fun onDependentViewRemoved(
|
||||
parent: CoordinatorLayout,
|
||||
child: V,
|
||||
dependency: View
|
||||
) = when (dependency) {
|
||||
is Snackbar.SnackbarLayout -> onDependentViewRemoved(parent, child, dependency)
|
||||
else -> super.onDependentViewRemoved(parent, child, dependency)
|
||||
}
|
||||
|
||||
//---
|
||||
|
||||
private fun onDependentViewChanged(
|
||||
parent: CoordinatorLayout,
|
||||
child: V,
|
||||
dependency: Snackbar.SnackbarLayout
|
||||
): Boolean {
|
||||
val viewMargin = (child.layoutParams as ViewGroup.MarginLayoutParams).bottomMargin
|
||||
val additionalMargin = dependency.resources.getDimension(R.dimen.l1).roundToInt()
|
||||
val translation = dependency.height + additionalMargin
|
||||
|
||||
dependency.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
bottomMargin = viewMargin
|
||||
}
|
||||
|
||||
// checks whether the navigation is not hidden via scroll
|
||||
if (child.isVisible && child.translationY <= 0) {
|
||||
child.translationY(-translation.toFloat())
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun onDependentViewRemoved(
|
||||
parent: CoordinatorLayout,
|
||||
child: V,
|
||||
dependency: Snackbar.SnackbarLayout
|
||||
) {
|
||||
// checks whether the navigation is not hidden via scroll
|
||||
if (child.isVisible && child.translationY <= 0) {
|
||||
child.translationY(0f)
|
||||
}
|
||||
}
|
||||
|
||||
//---
|
||||
|
||||
override fun slideUp(child: V) {
|
||||
if (lockState) return
|
||||
super.slideUp(child)
|
||||
}
|
||||
|
||||
override fun slideDown(child: V) {
|
||||
if (lockState) return
|
||||
super.slideDown(child)
|
||||
}
|
||||
|
||||
override fun setHidden(
|
||||
view: V,
|
||||
hide: Boolean,
|
||||
lockState: Boolean
|
||||
) {
|
||||
if (!lockState) {
|
||||
this.lockState = lockState
|
||||
}
|
||||
|
||||
if (hide || !Info.env.isActive) {
|
||||
// view is not laid out and drawn yet properly, so animation will not be attached
|
||||
// hence we just simply hide the view
|
||||
if (!isLaidOut) {
|
||||
view.isGone = true
|
||||
} else {
|
||||
slideDown(view)
|
||||
}
|
||||
} else {
|
||||
view.isVisible = Info.env.isActive
|
||||
slideUp(view)
|
||||
}
|
||||
|
||||
this.lockState = lockState
|
||||
}
|
||||
|
||||
//---
|
||||
|
||||
private fun View.translationY(destination: Float) = animate()
|
||||
.translationY(destination)
|
||||
.setInterpolator(FastOutSlowInInterpolator())
|
||||
.start()
|
||||
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
package com.topjohnwu.magisk.utils
|
||||
|
||||
import android.animation.TimeInterpolator
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewPropertyAnimator
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.view.ViewCompat
|
||||
import com.google.android.material.animation.AnimationUtils
|
||||
|
||||
class HideTopViewOnScrollBehavior<V : View>(context: Context, attrs: AttributeSet) :
|
||||
CoordinatorLayout.Behavior<V>(), HideableBehavior<V> {
|
||||
|
||||
companion object {
|
||||
private const val STATE_SCROLLED_DOWN = 1
|
||||
private const val STATE_SCROLLED_UP = 2
|
||||
|
||||
private const val ENTER_ANIMATION_DURATION = 225
|
||||
private const val EXIT_ANIMATION_DURATION = 175
|
||||
}
|
||||
|
||||
private var height = 0
|
||||
private var currentState = STATE_SCROLLED_UP
|
||||
private var currentAnimator: ViewPropertyAnimator? = null
|
||||
private var lockState: Boolean = false
|
||||
|
||||
override fun onLayoutChild(
|
||||
parent: CoordinatorLayout,
|
||||
child: V,
|
||||
layoutDirection: Int
|
||||
): Boolean {
|
||||
val paramsCompat = child.layoutParams as ViewGroup.MarginLayoutParams
|
||||
height = child.measuredHeight + paramsCompat.topMargin
|
||||
return super.onLayoutChild(parent, child, layoutDirection)
|
||||
}
|
||||
|
||||
override fun onStartNestedScroll(
|
||||
coordinatorLayout: CoordinatorLayout,
|
||||
child: V,
|
||||
directTargetChild: View,
|
||||
target: View,
|
||||
nestedScrollAxes: Int,
|
||||
type: Int
|
||||
) = nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL
|
||||
|
||||
override fun onNestedScroll(
|
||||
coordinatorLayout: CoordinatorLayout,
|
||||
child: V,
|
||||
target: View,
|
||||
dxConsumed: Int,
|
||||
dyConsumed: Int,
|
||||
dxUnconsumed: Int,
|
||||
dyUnconsumed: Int,
|
||||
type: Int,
|
||||
consumed: IntArray
|
||||
) {
|
||||
// when initiating scroll while the view is at the bottom or at the top and pushing it
|
||||
// further, the parent will report consumption of 0
|
||||
if (dyConsumed == 0) return
|
||||
|
||||
setHidden(child, dyConsumed > 0, false)
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun setHidden(
|
||||
view: V,
|
||||
hide: Boolean,
|
||||
lockState: Boolean
|
||||
) {
|
||||
if (!lockState) {
|
||||
this.lockState = lockState
|
||||
}
|
||||
|
||||
if (hide) {
|
||||
slideUp(view)
|
||||
} else {
|
||||
slideDown(view)
|
||||
}
|
||||
|
||||
this.lockState = lockState
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform an animation that will slide the child from it's current position to be totally on the
|
||||
* screen.
|
||||
*/
|
||||
private fun slideDown(child: V) {
|
||||
if (currentState == STATE_SCROLLED_UP || lockState) {
|
||||
return
|
||||
}
|
||||
|
||||
currentAnimator?.let {
|
||||
it.cancel()
|
||||
child.clearAnimation()
|
||||
}
|
||||
|
||||
currentState = STATE_SCROLLED_UP
|
||||
animateChildTo(
|
||||
child,
|
||||
0,
|
||||
ENTER_ANIMATION_DURATION.toLong(),
|
||||
AnimationUtils.LINEAR_OUT_SLOW_IN_INTERPOLATOR
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform an animation that will slide the child from it's current position to be totally off the
|
||||
* screen.
|
||||
*/
|
||||
private fun slideUp(child: V) {
|
||||
if (currentState == STATE_SCROLLED_DOWN || lockState) {
|
||||
return
|
||||
}
|
||||
|
||||
currentAnimator?.let {
|
||||
it.cancel()
|
||||
child.clearAnimation()
|
||||
}
|
||||
|
||||
currentState = STATE_SCROLLED_DOWN
|
||||
animateChildTo(
|
||||
child,
|
||||
-height,
|
||||
EXIT_ANIMATION_DURATION.toLong(),
|
||||
AnimationUtils.FAST_OUT_LINEAR_IN_INTERPOLATOR
|
||||
)
|
||||
}
|
||||
|
||||
private fun animateChildTo(
|
||||
child: V,
|
||||
targetY: Int,
|
||||
duration: Long,
|
||||
interpolator: TimeInterpolator
|
||||
) = child
|
||||
.animate()
|
||||
.translationY(targetY.toFloat())
|
||||
.setInterpolator(interpolator)
|
||||
.setDuration(duration)
|
||||
.withEndAction { currentAnimator = null }
|
||||
.let { currentAnimator = it }
|
||||
}
|
||||
Reference in New Issue
Block a user