J'essaie d'utiliser à la fois AppBarLayout
et BottomNavigationLayout
dans une seule CoordinatorLayout
et j'ai du mal à cacher la BottomNavigationLayout
comme l'exige la directive material .
Je veux dire quelque chose comme ça:
<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>
Comme vous pouvez le constater, j'ai aussi une variable FrameLayout
qui contient un fragment avec le contenu réel. Actuellement, il n'y a pas de comportement par défaut/intégré pour la variable BottomNavigationView
- ni pour la vue elle-même, ni pour ses frères et soeurs. Le appbar_scrolling_view_behavior
existant gère la vue du contenu en coordination avec la barre d’application mais ignore les autres frères et soeurs.
Je recherche une solution pour masquer et afficher à la fois la barre d’application et la vue de navigation inférieure en défilement.
Après un jour ou deux de recherches, je me suis installé avec une coutume Behavior
attachée à la BottomNavigationView
. Son idée principale est de détecter le défilement du frère de BottomNavigationView afin qu'il puisse masquer le BottomNavigationView. Quelque chose comme ça:
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);
}
}
Comme vous pouvez le constater, j'utilise la méthode ViewPropertyAnimator
simple, obtenue à l'aide de la méthode animate
de la vue enfant. Cela conduit à une animation simple qui ne correspond pas vraiment au comportement de AppBarLayout
mais qui est suffisamment décente pour paraître belle et en même temps assez simple pour être mise en œuvre.
Je pense qu’à un moment donné, l’équipe Android ajoutera un comportement par défaut pour BottomNavigationView dans la bibliothèque de support technique. Par conséquent, je ne pense pas qu’il soit raisonnable d’investir plus de temps pour dupliquer exactement le comportement de AppBarLayout.
edit (avril 2018): voir la section des commentaires pour une clarification mineure à propos de onStartNestedScroll
et onNestedPreScroll
et de leurs nouvelles versions.
Vous pouvez également utiliser HideBottomViewOnScrollBehavior . Ce comportement fonctionne fondamentalement de la même manière, mais gère également l'annulation de toutes les animations existantes en cours d'exécution qui devraient être meilleures pour la performance.