Fix bottom navigation insets #1341

This commit is contained in:
Koitharu
2025-04-03 13:19:10 +03:00
parent e4b9da54dd
commit 42b2f21c4d
2 changed files with 59 additions and 10 deletions

View File

@@ -8,7 +8,7 @@ import android.view.animation.DecelerateInterpolator
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 com.google.android.material.navigation.NavigationBarView
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.util.ext.getAnimationDuration
import org.koitharu.kotatsu.core.util.ext.measureHeight
@@ -16,7 +16,7 @@ import org.koitharu.kotatsu.core.util.ext.measureHeight
class HideBottomNavigationOnScrollBehavior @JvmOverloads constructor(
context: Context? = null,
attrs: AttributeSet? = null,
) : CoordinatorLayout.Behavior<BottomNavigationView>(context, attrs) {
) : CoordinatorLayout.Behavior<NavigationBarView>(context, attrs) {
@ViewCompat.NestedScrollType
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
}
override fun onDependentViewChanged(
parent: CoordinatorLayout,
child: BottomNavigationView,
child: NavigationBarView,
dependency: View,
): Boolean {
val appBarSize = dependency.measureHeight()
@@ -54,7 +54,7 @@ class HideBottomNavigationOnScrollBehavior @JvmOverloads constructor(
override fun onStartNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: BottomNavigationView,
child: NavigationBarView,
directTargetChild: View,
target: View,
axes: Int,
@@ -70,7 +70,7 @@ class HideBottomNavigationOnScrollBehavior @JvmOverloads constructor(
override fun onNestedPreScroll(
coordinatorLayout: CoordinatorLayout,
child: BottomNavigationView,
child: NavigationBarView,
target: View,
dx: Int,
dy: Int,
@@ -85,7 +85,7 @@ class HideBottomNavigationOnScrollBehavior @JvmOverloads constructor(
override fun onStopNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: BottomNavigationView,
child: NavigationBarView,
target: View,
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 = ValueAnimator().apply {
interpolator = DecelerateInterpolator()

View File

@@ -3,10 +3,12 @@ package org.koitharu.kotatsu.core.ui.widgets
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.TimeInterpolator
import android.annotation.SuppressLint
import android.content.Context
import android.os.Parcel
import android.os.Parcelable
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.ViewPropertyAnimator
import androidx.annotation.AttrRes
import androidx.annotation.StyleRes
@@ -15,9 +17,11 @@ import androidx.core.view.isVisible
import androidx.customview.view.AbsSavedState
import androidx.interpolator.view.animation.FastOutLinearInInterpolator
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.measureHeight
import kotlin.math.max
import com.google.android.material.R as materialR
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_DOWN_ANIMATION_DURATION = 175L
private const val MAX_ITEM_COUNT = 6
class SlidingBottomNavigationView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
@AttrRes defStyleAttr: Int = materialR.attr.bottomNavigationStyle,
@StyleRes defStyleRes: Int = materialR.style.Widget_Design_BottomNavigationView,
) : BottomNavigationView(context, attrs, defStyleAttr, defStyleRes),
) : NavigationBarView(context, attrs, defStyleAttr, defStyleRes),
CoordinatorLayout.AttachedBehavior {
private var currentAnimator: ViewPropertyAnimator? = null
@@ -55,6 +61,49 @@ class SlidingBottomNavigationView @JvmOverloads constructor(
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 {
val superState = super.onSaveInstanceState()
return SavedState(superState, currentState, translationY)