Google a publié la bibliothèque de conception, j'utilise
compile 'com.Android.support:design:22.2.1'
Cependant, je ne peux pas voir d'exemples de code sur la façon d'utiliser cette bibliothèque et d'animer la barre FAB
en défilement. Je suppose que je peux écouter les événements de défilement sur le ListView
puis animer le bouton moi-même, mais ce n'est pas intégré dans l'API (n'est-ce pas le but de cette bibliothèque de support).
Y a-t-il des exemples pour cela?
Si vous utilisez RecyclerView
et que vous cherchez quelque chose de simple, vous pouvez essayer ceci:
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener(){
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy){
if (dy > 0)
fabAddNew.hide();
else if (dy < 0)
fabAddNew.show();
}
});
En remplaçant 0
avec une constante, vous pouvez régler la sensibilité du déclenchement, offrant une expérience plus fluide
Faire réagir un composant aux événements de défilement se fait le plus facilement avec un CoordinatorLayout.Behavior personnalisé, car ils reçoivent automatiquement les événements de défilement lorsque vous remplacez onStartNestedScroll () .
Un exemple de comportement qui masque et affiche le FAB sur le défilement trouvé dans ce FABAwareScrollingViewBehavior , construit au-dessus de cheesesquare :
public class FABAwareScrollingViewBehavior
extends AppBarLayout.ScrollingViewBehavior {
public FABAwareScrollingViewBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent,
View child, View dependency) {
return super.layoutDependsOn(parent, child, dependency) ||
dependency instanceof FloatingActionButton;
}
@Override
public boolean onStartNestedScroll(
final CoordinatorLayout coordinatorLayout, final View child,
final View directTargetChild, final View target,
final int nestedScrollAxes) {
// Ensure we react to vertical scrolling
return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL
|| super.onStartNestedScroll(coordinatorLayout, child,
directTargetChild, target, nestedScrollAxes);
}
@Override
public void onNestedScroll(
final CoordinatorLayout coordinatorLayout, final View child,
final View target, final int dxConsumed, final int dyConsumed,
final int dxUnconsumed, final int dyUnconsumed) {
super.onNestedScroll(coordinatorLayout, child, target,
dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
if (dyConsumed > 0) {
// User scrolled down -> hide the FAB
List<View> dependencies = coordinatorLayout.getDependencies(child);
for (View view : dependencies) {
if (view instanceof FloatingActionButton) {
((FloatingActionButton) view).hide();
}
}
} else if (dyConsumed < 0) {
// User scrolled up -> show the FAB
List<View> dependencies = coordinatorLayout.getDependencies(child);
for (View view : dependencies) {
if (view instanceof FloatingActionButton) {
((FloatingActionButton) view).show();
}
}
}
}
}
Où votre vue de défilement aurait app:layout_behavior="com.support.Android.designlibdemo.FABAwareScrollingViewBehavior"
Au lieu de app:layout_behavior="@string/appbar_scrolling_view_behavior"
Cependant, vous pouvez remplacer hide()
et show()
par n'importe quelle action si vous le souhaitez. Des détails sur la façon dont cela a été fait peuvent être trouvés dans ce post et le post de suivi pour v22.2.1 et le post de suivi pour v25 .1.0 .
Notez que cela, comme tous les comportements de défilement de la bibliothèque de conception, nécessite que votre vue prenne en charge le défilement imbriqué, ce qui vous limite actuellement à NestedScrollView , RecyclerView - ListView
et ScrollView
ne fonctionnent que sur les appareils API21 +.
Si vous êtes NE PAS en utilisant un RecycleView (c'est-à-dire, juste régulier ScrollView) Ça fera l'affaire:
mScrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
@Override
public void onScrollChanged() {
if (mScrollView.getScrollY() > oldScrollYPostion) {
fab.hide();
} else if (mScrollView.getScrollY() < oldScrollYPostion || mScrollView.getScrollY() <= 0) {
fab.show();
}
oldScrollYPostion = mScrollView.getScrollY();
}
});
N'oubliez pas de déclarer:
private int oldScrollYPostion = 0;
à l'intérieur de votre classe.
Utiliser CoordinatorLayout est le meilleur moyen. Cependant, si vous souhaitez attacher un écouteur à ListView ou RecyclerView, vous pouvez également le faire. Je pense que c'est plus personnalisable. Voici mon exemple sur git hub.
Projet Github: Masquer FAB (bibliothèque de matériaux) avec listview
Le @ianhanniballake fonctionne bien mais les méthodes onStartNestedScroll()
et onNestedScroll()
étaient obsolètes. Voici la version mise à jour:
public class FabAwareScrollingViewBehavior extends AppBarLayout.ScrollingViewBehavior {
public FabAwareScrollingViewBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
return super.layoutDependsOn(parent, child, dependency) ||
dependency instanceof FloatingActionButton;
}
@Override
public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout,
@NonNull View child, @NonNull View directTargetChild,
@NonNull View target, int axes, int type) {
// Ensure we react to vertical scrolling
return axes == ViewCompat.SCROLL_AXIS_VERTICAL ||
super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, axes, type);
}
@Override
public void onNestedPreScroll(@NonNull CoordinatorLayout coordinatorLayout,
@NonNull View child, @NonNull View target, int dx, int dy,
@NonNull int[] consumed, int type) {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);
if (dy > 0) {
// User scrolled down -> hide the FAB
List<View> dependencies = coordinatorLayout.getDependencies(child);
for (View view : dependencies) {
if (view instanceof FloatingActionButton) {
((FloatingActionButton) view).hide();
}
}
} else if (dy < 0) {
// User scrolled up -> show the FAB
List<View> dependencies = coordinatorLayout.getDependencies(child);
for (View view : dependencies) {
if (view instanceof FloatingActionButton) {
((FloatingActionButton) view).show();
}
}
}
}
}
Il y a aussi un très bon article de @ianhanniballake sur ce sujet: Tout intercepter avec des comportements de coordinateur
recyclerView.setOnFlingListener(new RecyclerView.OnFlingListener() {
@Override
public boolean onFling(int velocityX, int velocityY) {
if (velocityY < 0)
mScrollCallbacks.showUI();
//Code to hide the UI, I have a custom one that slides down the nav bar and the fab
else if (velocityY > 0)
mScrollCallbacks.hideUI();
//Code to show the UI
return false;
}
});
Cela fonctionne très bien