AppBarLayout
とBottomNavigationLayout
の両方を1つのCoordinatorLayout
で使用しようとしていますが、 材料ガイドライン の要件に従って、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と連携してコンテンツビューを処理しますが、他の兄弟は無視します。
Appbarとスクロール時に下部ナビゲーションビューの両方を非表示および表示するソリューションを探しています。
1〜2日検索した後、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の動作を正確に複製するために多くの時間を費やすことは妥当ではないと思います。
edit(2018年4月):onStartNestedScroll
とonNestedPreScroll
とそれらの新しいバージョンに関する簡単な説明については、コメントセクションを参照してください。
HideBottomViewOnScrollBehavior を使用することもできます。この動作は基本的に同じ方法で機能しますが、パフォーマンスを向上させるために実行中の既存のアニメーションのキャンセルも処理します。