Fix bottom navigation insets #1341

master
Koitharu 1 year ago
parent e4b9da54dd
commit 42b2f21c4d
Signed by: Koitharu
GPG Key ID: 676DEE768C17A9D7

@ -8,7 +8,7 @@ import android.view.animation.DecelerateInterpolator
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.navigation.NavigationBarView
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.util.ext.getAnimationDuration import org.koitharu.kotatsu.core.util.ext.getAnimationDuration
import org.koitharu.kotatsu.core.util.ext.measureHeight import org.koitharu.kotatsu.core.util.ext.measureHeight
@ -16,7 +16,7 @@ import org.koitharu.kotatsu.core.util.ext.measureHeight
class HideBottomNavigationOnScrollBehavior @JvmOverloads constructor( class HideBottomNavigationOnScrollBehavior @JvmOverloads constructor(
context: Context? = null, context: Context? = null,
attrs: AttributeSet? = null, attrs: AttributeSet? = null,
) : CoordinatorLayout.Behavior<BottomNavigationView>(context, attrs) { ) : CoordinatorLayout.Behavior<NavigationBarView>(context, attrs) {
@ViewCompat.NestedScrollType @ViewCompat.NestedScrollType
private var lastStartedType: Int = 0 private var lastStartedType: Int = 0
@ -34,13 +34,13 @@ class HideBottomNavigationOnScrollBehavior @JvmOverloads constructor(
} }
} }
override fun layoutDependsOn(parent: CoordinatorLayout, child: BottomNavigationView, dependency: View): Boolean { override fun layoutDependsOn(parent: CoordinatorLayout, child: NavigationBarView, dependency: View): Boolean {
return dependency is AppBarLayout return dependency is AppBarLayout
} }
override fun onDependentViewChanged( override fun onDependentViewChanged(
parent: CoordinatorLayout, parent: CoordinatorLayout,
child: BottomNavigationView, child: NavigationBarView,
dependency: View, dependency: View,
): Boolean { ): Boolean {
val appBarSize = dependency.measureHeight() val appBarSize = dependency.measureHeight()
@ -54,7 +54,7 @@ class HideBottomNavigationOnScrollBehavior @JvmOverloads constructor(
override fun onStartNestedScroll( override fun onStartNestedScroll(
coordinatorLayout: CoordinatorLayout, coordinatorLayout: CoordinatorLayout,
child: BottomNavigationView, child: NavigationBarView,
directTargetChild: View, directTargetChild: View,
target: View, target: View,
axes: Int, axes: Int,
@ -70,7 +70,7 @@ class HideBottomNavigationOnScrollBehavior @JvmOverloads constructor(
override fun onNestedPreScroll( override fun onNestedPreScroll(
coordinatorLayout: CoordinatorLayout, coordinatorLayout: CoordinatorLayout,
child: BottomNavigationView, child: NavigationBarView,
target: View, target: View,
dx: Int, dx: Int,
dy: Int, dy: Int,
@ -85,7 +85,7 @@ class HideBottomNavigationOnScrollBehavior @JvmOverloads constructor(
override fun onStopNestedScroll( override fun onStopNestedScroll(
coordinatorLayout: CoordinatorLayout, coordinatorLayout: CoordinatorLayout,
child: BottomNavigationView, child: NavigationBarView,
target: View, target: View,
type: Int, type: Int,
) { ) {
@ -94,7 +94,7 @@ class HideBottomNavigationOnScrollBehavior @JvmOverloads constructor(
} }
} }
private fun animateBottomNavigationVisibility(child: BottomNavigationView, isVisible: Boolean) { private fun animateBottomNavigationVisibility(child: NavigationBarView, isVisible: Boolean) {
offsetAnimator?.cancel() offsetAnimator?.cancel()
offsetAnimator = ValueAnimator().apply { offsetAnimator = ValueAnimator().apply {
interpolator = DecelerateInterpolator() interpolator = DecelerateInterpolator()

@ -3,10 +3,12 @@ package org.koitharu.kotatsu.core.ui.widgets
import android.animation.Animator import android.animation.Animator
import android.animation.AnimatorListenerAdapter import android.animation.AnimatorListenerAdapter
import android.animation.TimeInterpolator import android.animation.TimeInterpolator
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.os.Parcel import android.os.Parcel
import android.os.Parcelable import android.os.Parcelable
import android.util.AttributeSet import android.util.AttributeSet
import android.view.MotionEvent
import android.view.ViewPropertyAnimator import android.view.ViewPropertyAnimator
import androidx.annotation.AttrRes import androidx.annotation.AttrRes
import androidx.annotation.StyleRes import androidx.annotation.StyleRes
@ -15,9 +17,11 @@ import androidx.core.view.isVisible
import androidx.customview.view.AbsSavedState import androidx.customview.view.AbsSavedState
import androidx.interpolator.view.animation.FastOutLinearInInterpolator import androidx.interpolator.view.animation.FastOutLinearInInterpolator
import androidx.interpolator.view.animation.LinearOutSlowInInterpolator import androidx.interpolator.view.animation.LinearOutSlowInInterpolator
import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.bottomnavigation.BottomNavigationMenuView
import com.google.android.material.navigation.NavigationBarView
import org.koitharu.kotatsu.core.util.ext.applySystemAnimatorScale import org.koitharu.kotatsu.core.util.ext.applySystemAnimatorScale
import org.koitharu.kotatsu.core.util.ext.measureHeight import org.koitharu.kotatsu.core.util.ext.measureHeight
import kotlin.math.max
import com.google.android.material.R as materialR import com.google.android.material.R as materialR
private const val STATE_DOWN = 1 private const val STATE_DOWN = 1
@ -26,12 +30,14 @@ private const val STATE_UP = 2
private const val SLIDE_UP_ANIMATION_DURATION = 225L private const val SLIDE_UP_ANIMATION_DURATION = 225L
private const val SLIDE_DOWN_ANIMATION_DURATION = 175L private const val SLIDE_DOWN_ANIMATION_DURATION = 175L
private const val MAX_ITEM_COUNT = 6
class SlidingBottomNavigationView @JvmOverloads constructor( class SlidingBottomNavigationView @JvmOverloads constructor(
context: Context, context: Context,
attrs: AttributeSet? = null, attrs: AttributeSet? = null,
@AttrRes defStyleAttr: Int = materialR.attr.bottomNavigationStyle, @AttrRes defStyleAttr: Int = materialR.attr.bottomNavigationStyle,
@StyleRes defStyleRes: Int = materialR.style.Widget_Design_BottomNavigationView, @StyleRes defStyleRes: Int = materialR.style.Widget_Design_BottomNavigationView,
) : BottomNavigationView(context, attrs, defStyleAttr, defStyleRes), ) : NavigationBarView(context, attrs, defStyleAttr, defStyleRes),
CoordinatorLayout.AttachedBehavior { CoordinatorLayout.AttachedBehavior {
private var currentAnimator: ViewPropertyAnimator? = null private var currentAnimator: ViewPropertyAnimator? = null
@ -55,6 +61,49 @@ class SlidingBottomNavigationView @JvmOverloads constructor(
return behavior return behavior
} }
/** From BottomNavigationView **/
@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(event: MotionEvent): Boolean {
super.onTouchEvent(event)
// Consume all events to avoid views under the BottomNavigationView from receiving touch events.
return true
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val minHeightSpec = makeMinHeightSpec(heightMeasureSpec)
super.onMeasure(widthMeasureSpec, minHeightSpec)
if (MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY) {
setMeasuredDimension(
measuredWidth,
max(
measuredHeight,
suggestedMinimumHeight + paddingTop + paddingBottom,
),
)
}
}
private fun makeMinHeightSpec(measureSpec: Int): Int {
var minHeight = suggestedMinimumHeight
if (MeasureSpec.getMode(measureSpec) != MeasureSpec.EXACTLY && minHeight > 0) {
minHeight += paddingTop + paddingBottom
return MeasureSpec.makeMeasureSpec(
max(MeasureSpec.getSize(measureSpec), minHeight), MeasureSpec.AT_MOST,
)
}
return measureSpec
}
override fun getMaxItemCount(): Int = MAX_ITEM_COUNT
@SuppressLint("RestrictedApi")
override fun createNavigationBarMenuView(context: Context) = BottomNavigationMenuView(context)
/** End **/
override fun onSaveInstanceState(): Parcelable { override fun onSaveInstanceState(): Parcelable {
val superState = super.onSaveInstanceState() val superState = super.onSaveInstanceState()
return SavedState(superState, currentState, translationY) return SavedState(superState, currentState, translationY)

Loading…
Cancel
Save