Показать / скрыть BottomNavigationView при прокрутке в CoordinatorLayout с помощью AppBarLayout
Я пытаюсь использовать оба AppBarLayout
а также BottomNavigationLayout
в одном 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
обрабатывает представление содержимого в координации с панелью приложения, но игнорирует других братьев и сестер.
Я ищу решение, чтобы скрыть и показать как панель приложения, так и нижнюю навигационную панель при прокрутке.
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.
редактировать (апрель 2018 г.): см. раздел с комментариями для небольшого разъяснения о onStartNestedScroll
а также onNestedPreScroll
и их новые версии.
Вы также можете использовать HideBottomViewOnScrollBehavior. Это поведение работает в основном таким же образом, но также обрабатывает отмену любых существующих анимаций, которые работают, что должно быть лучше для производительности.