14

我正在尝试同时使用两者AppBarLayout,并且我很难按照材料指南的BottomNavigationLayout要求隐藏它们。CoordinatorLayoutBottomNavigationLayout

我的意思是这样的:

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="false">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_insetEdge="top"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:popupTheme="@style/AppTheme.PopupOverlay"
            app:layout_scrollFlags="scroll|enterAlways"/>
    </android.support.design.widget.AppBarLayout>


    <android.support.design.widget.BottomNavigationView
        android:id="@+id/bottom_nav"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:layout_gravity="bottom"
        app:menu="@menu/menu_bottom_navigation"/>

    <FrameLayout
        android:id="@+id/content_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

</android.support.design.widget.CoordinatorLayout>

如您所见,我还有一个FrameLayout用于包含具有实际内容的片段。目前没有默认/内置的行为BottomNavigationView- 既不是视图本身,也不是它的兄弟姐妹。现有的appbar_scrolling_view_behavior处理与 appbar 协调的内容视图,但忽略其他兄弟。

我正在寻找一种在滚动时隐藏和显示 appbar 和底部导航视图的解决方案。

4

2 回答 2

23

经过一两天的搜索,我确定了一个Behavior附加到BottomNavigationView. 它的主要思想是检测BottomNavigationView的兄弟何时滚动,以便它可以隐藏BottomNavigationView。像这样的东西:

public class BottomNavigationBehavior extends CoordinatorLayout.Behavior<BottomNavigationView> {

    public BottomNavigationBehavior() {
        super();
    }

    public BottomNavigationBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, BottomNavigationView child, View dependency) {
        boolean dependsOn = dependency instanceof FrameLayout;
        return dependsOn;
    }

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, BottomNavigationView child, View directTargetChild, View target, int nestedScrollAxes) {
        return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL;
    }

    @Override
    public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, BottomNavigationView child, View target, int dx, int dy, int[] consumed) {
        if(dy < 0) {
            showBottomNavigationView(child);
        }
        else if(dy > 0) {
            hideBottomNavigationView(child);
        }
    }

    private void hideBottomNavigationView(BottomNavigationView view) {
        view.animate().translationY(view.getHeight());
    }

    private void showBottomNavigationView(BottomNavigationView view) {
        view.animate().translationY(0);
    }
}

如您所见,我使用ViewPropertyAnimator的是简单的,使用子视图的animate方法获得的。这导致了一个简单的动画,它与 ' 的行为并不真正匹配,AppBarLayout但它足够体面,看起来不错,同时它也足够简单实现。

我希望 Android 团队在某个时候会在支持库中为 BottomNavigationView 添加默认行为,因此我认为投入更多时间来完全复制 AppBarLayout 的行为是不合理的。

编辑(2018 年 4 月):请参阅评论部分,了解有关及其新版本的小onStartNestedScroll说明onNestedPreScroll

于 2017-03-06T17:11:00.307 回答
4

您还可以使用HideBottomViewOnScrollBehavior。此行为以基本相同的方式工作,但也处理取消任何正在运行的现有动画,这应该更好地提高性能。

于 2018-05-17T16:33:46.367 回答