我试图在一个CoordinatorLayout中同时使用AppBarLayout和BottomNavigationLayout,并且我很难按照
material guideline的要求隐藏BottomNavigationLayout.
我的意思是这样的:
<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协调处理内容视图,但忽略其他兄弟.
解决方法
经过一两天的搜索后,我决定使用附加到BottomNavigationView的自定义
Behavior
.它的主要思想是检测何时滚动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,View directTargetChild,View target,int nestedScrollAxes) { return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL; } @Override public void onNestedPreScroll(CoordinatorLayout coordinatorLayout,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及其新版本的详细说明,请参阅注释部分.