使用 AppBarLayout 在 CoordinatorLayout 中滚动时显示/隐藏 BottomNavigationView [英] Show/hide BottomNavigationView on scroll in CoordinatorLayout with AppBarLayout

查看:23
本文介绍了使用 AppBarLayout 在 CoordinatorLayout 中滚动时显示/隐藏 BottomNavigationView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在一个 CoordinatorLayout 中同时使用 AppBarLayoutBottomNavigationLayout,但我在隐藏 BottomNavigationLayout 按照材料指南的要求.

I am trying to use both AppBarLayout and BottomNavigationLayout in a single CoordinatorLayout and I'm having difficulties hiding the BottomNavigationLayout as required by the material guideline.

我的意思是这样的:

<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 协调处理内容视图,但忽略其他兄弟.

As you can see, I also have a FrameLayout that's used to contain a fragment with the actual content. Currently there are no default/built-in behaviors for the BottomNavigationView - neither for the view itself, nor for its siblings. The existing appbar_scrolling_view_behavior handles the content view in coordination with the appbar but ignores other siblings.

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

I am looking for a solution to hide and show both the appbar and the bottom navigation view on scroll.

推荐答案

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

After a day or two of searching I settled with a custom Behavior attached to the BottomNavigationView. Its main idea is to detect when the BottomNavigationView's sibling is scrolled so that it can hide the BottomNavigationView. Something like this:

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,使用子视图的 获得动画 方法.这导致了一个简单的动画,它与 AppBarLayout 的行为并不真正匹配,但它看起来不错,同时它也很容易实现.

As you can see, I'm using simple ViewPropertyAnimator, obtained using the child views's animate method. This leads to a simple animation that doesn't really match the AppBarLayout's behavior but it's decent enough to look good and at the same time it's simple enough to implement.

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

I expect that at some point the Android team will add a default Behavior for the BottomNavigationView in the support library so I don't think it's reasonable to invest a lot more time to exactly duplicate the AppBarLayout's behavior.

edit(2018 年 4 月):有关 onStartNestedScrollonNestedPreScroll 及其新版本的小说明,请参阅评论部分.

edit (April 2018): see the comments section for a minor clarification about onStartNestedScroll and onNestedPreScroll and their new versions.

这篇关于使用 AppBarLayout 在 CoordinatorLayout 中滚动时显示/隐藏 BottomNavigationView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆