如何实现滚动行为,其中工具栏和底部导航都应该隐藏?只有其中一个在工作

How do I achieve on scroll behavior where both the toolbar and bottom navigation should hide?Only one of them is working

我正在尝试实现协调器布局行为,在滚动回收器视图时可以隐藏工具栏和底部导航视图。到目前为止,我已经取得了一项成功,即底部导航底部栏确实隐藏了,但有一个警告,即使键盘打开它也保持活动状态(我该如何解决这个问题?) 我主要关心的是如何实现隐藏到工具栏中的底部导航视图的相同功能?

我已经在 Appbar 布局中包含了自定义工具栏,但我也尝试在 AppBar 中添加工具栏布局标签没有任何效果,它只是保持不变。 对于跳到顶部的底部导航,我不知道该怎么办?到目前为止,我已经在底部导航视图上添加了 snap 滚动标志以停止此行为,并且快照标志也不起作用,我认为是这样,因为它在搜索点击时保持在中间位置。 从精彩的文章中获得了这个 BottomNavigationBehavior。

reference

video showing behavior

image for snap behavior

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
>
    <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="?actionBarSize"
            app:elevation="0dp"
            android:background="@android:color/transparent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
    >
        <include
                app:layout_scrollFlags="scroll|enterAlways|snap"
                layout="@layout/browser_search_tap_tb"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/browser_tb"

        />
    </com.google.android.material.appbar.AppBarLayout>
    <!--Scrolling effect for the bottom nav menu-->
    <androidx.recyclerview.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:listitem="@layout/rv_test_items"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            android:id="@+id/rv_test"
    />
    <!--Bottom navigation view for the Selection of the Tabs and Items in Menu-->
    <com.google.android.material.bottomnavigation.BottomNavigationView
            app:layout_scrollFlags="scroll|enterAlways|snap"
            android:id="@+id/browser_bottom_nav_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:background="#ffff"
            app:layout_behavior="com.example.android.browserui.BottomNavigationBehavior"
            app:labelVisibilityMode="unlabeled"
            app:menu="@menu/bottom_nav_menu"
    />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

browser_search_tap_tb.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.Toolbar
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="?actionBarSize"
        android:background="@android:color/transparent"
        app:layout_scrollFlags="scroll|enterAlways"
        app:popupTheme="@style/ThemeOverlay.AppCompat"
        app:contentInsetStart="8dp"
        app:contentInsetEnd="8dp"
>
    <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
        <EditText
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:hint="Search or type new address"
                android:padding="8dp"
                android:paddingEnd="12dp"
                android:paddingStart="12dp"
                android:drawableEnd="@drawable/ic_mic"
                android:inputType="textWebEditText"
                android:background="@drawable/rounded_et_search"
                app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintBottom_toBottomOf="parent" android:id="@+id/et_search_bar_tap"
                app:layout_constraintEnd_toEndOf="parent"/>
    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.appcompat.widget.Toolbar>

BottomNavigationBehavior.kt

class BottomNavigationBehavior<V : View>(context: Context, attrs: AttributeSet) :
    CoordinatorLayout.Behavior<V>(context, attrs) {

    private var lastStartedType: Int = 0

    private var offsetAnimator: ValueAnimator? = null

    var isSnappingEnabled = false

    override fun layoutDependsOn(parent: CoordinatorLayout, child: V, dependency: View): Boolean {
        if (dependency is Snackbar.SnackbarLayout) {
            updateSnackbar(child, dependency)
        }
        return super.layoutDependsOn(parent, child, dependency)
    }

    override fun onStartNestedScroll(
        coordinatorLayout: CoordinatorLayout, child: V, directTargetChild: View, target: View, axes: Int, type: Int
    ): Boolean {
        if (axes != ViewCompat.SCROLL_AXIS_VERTICAL)
            return false

        lastStartedType = type

        offsetAnimator?.cancel()

        return true
    }

    override fun onNestedPreScroll(
        coordinatorLayout: CoordinatorLayout, child: V, target: View, dx: Int, dy: Int, consumed: IntArray, type: Int
    ) {
        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type)
        child.translationY = max(0f, min(child.height.toFloat(), child.translationY + dy))
    }

    override fun onStopNestedScroll(coordinatorLayout: CoordinatorLayout, child: V, target: View, type: Int) {
        if (!isSnappingEnabled)
            return

        // add snap behaviour
        // Logic here borrowed from AppBarLayout onStopNestedScroll code
        if (lastStartedType == ViewCompat.TYPE_TOUCH || type == ViewCompat.TYPE_NON_TOUCH) {
            // find nearest seam
            val currTranslation = child.translationY
            val childHalfHeight = child.height * 0.5f

            // translate down
            if (currTranslation >= childHalfHeight) {
                animateBarVisibility(child, isVisible = false)
            }
            // translate up
            else {
                animateBarVisibility(child, isVisible = true)
            }
        }
    }

    private fun animateBarVisibility(child: View, isVisible: Boolean) {
        if (offsetAnimator == null) {
            offsetAnimator = ValueAnimator().apply {
                interpolator = DecelerateInterpolator()
                duration = 150L
            }

            offsetAnimator?.addUpdateListener {
                child.translationY = it.animatedValue as Float
            }
        } else {
            offsetAnimator?.cancel()
        }

        val targetTranslation = if (isVisible) 0f else child.height.toFloat()
        offsetAnimator?.setFloatValues(child.translationY, targetTranslation)
        offsetAnimator?.start()
    }

    private fun updateSnackbar(child: View, snackbarLayout: Snackbar.SnackbarLayout) {
        if (snackbarLayout.layoutParams is CoordinatorLayout.LayoutParams) {
            val params = snackbarLayout.layoutParams as CoordinatorLayout.LayoutParams

            params.anchorId = child.id
            params.anchorGravity = Gravity.TOP
            params.gravity = Gravity.TOP
            snackbarLayout.layoutParams = params
        }
    }
}

所以终于解决了我的问题,经过 4 天的思考,这里是我所做的一些更改并解决了问题: activity_main.xml

<com.google.android.material.appbar.AppBarLayout
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="?actionBarSize"
            app:elevation="0dp"
            android:background="@android:color/transparent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"<!--Removed this line-->
    >


<!--Bottom navigation view for the Selection of the Tabs and Items in Menu-->
    <com.google.android.material.bottomnavigation.BottomNavigationView
            app:layout_scrollFlags="scroll|enterAlways|snap"<!--Removed this line-->
            android:id="@+id/browser_bottom_nav_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:background="#ffff"
            app:layout_behavior="com.example.android.browserui.BottomNavigationBehavior"
            app:labelVisibilityMode="unlabeled"
            app:menu="@menu/bottom_nav_menu"
    />

在 activity_main.xml 中,我删除了 layout_behavior 因为 appbar 本身正在调用其他布局项的滚动行为,它充当父项。

app:layout_behavior="@string/appbar_scrolling_view_behavior"

还从底部导航视图中删除了 scrollflags,因为我从 Class BottomNavigationBehavior.kt 实现了此行为,您可以在下面找到实现

app:layout_scrollFlags="scroll|enterAlways|snap"

browser_search_tap_tb.xml


<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.Toolbar
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="?actionBarSize"
        android:background="@android:color/transparent"
        app:layout_scrollFlags="scroll|enterAlways" <!--Removed this line-->
        app:popupTheme="@style/ThemeOverlay.AppCompat"
        app:contentInsetStart="8dp"
        app:contentInsetEnd="8dp"
>

在 browser_search_tb 中,我删除了以下行,因为它覆盖了协调器布局中的 Scrollflags,因此将其删除并且它完美地工作

app:layout_scrollFlags="scroll|enterAlways"

BottomNavigationBehavior.kt

override fun onStopNestedScroll(coordinatorLayout: CoordinatorLayout, child: V, target: View, type: Int) {
        if (!isSnappingEnabled)
           return // removed this line
{
        // add snap behaviour
        // Logic here borrowed from AppBarLayout onStopNestedScroll code
        if (lastStartedType == ViewCompat.TYPE_TOUCH || type == ViewCompat.TYPE_NON_TOUCH) {
            // find nearest seam
            val currTranslation = child.translationY
            val childHalfHeight = child.height * 0.5f

            // translate down
            if (currTranslation >= childHalfHeight) {
                animateBarVisibility(child, isVisible = false)
            }
            // translate up
            else {
                animateBarVisibility(child, isVisible = true)
            }
        }
}
}

这里我去掉了

return

并在 if 语句中添加了大括号{},并且 snap 功能正常工作

希望这个回答能对您有所帮助,并减少您的调试时间。 上面的参考资料是您可以在互联网上找到的关于滚动行为的最好的文章之一,它简单易懂