J'essaie d'obtenir un effet similaire à celui de WhatsApp, dans lequel la barre d'outils (lorsque vous la faites défiler) se clipse dans une vue semblable à celle d'un aimant ou non visible.
Ce que j'ai dans mon XML MainActivity:
app:layout_scrollFlags="scroll|enterAlways"
Maintenant, ne vous méprenez pas, cela fonctionne. Lorsque je fais défiler la barre d’outils est poussé hors de vue mais que j’arrête de faire défiler à mi-chemin, la barre d’outils reste à moitié cachée et à moitié invisible,.
Comment puis-je aborder la résolution de ce problème, car je souhaite qu'il soit visible ou invisible.
Cette fonctionnalité a été ajoutée à la version 23.1.0
de la bibliothèque de support Android. À partir des notes de publication:
Ajout de la prise en charge de la capture Edge à la classe AppBarLayout en ajoutant le fichier SCROLL_FLAG_SNAP constante. Lorsque le défilement se termine, si la vue est uniquement partiellement visible, la vue est capturée et défilée au plus proche Bord.
<Android.support.design.widget.CoordinatorLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<Android.support.design.widget.AppBarLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<Android.support.v7.widget.Toolbar
Android:id="@+id/toolbar"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|enterAlways|snap" />
-----
-----
Pour plus d'informations: http://Android-developers.blogspot.in/2015/10/Android-support-library-231.html
EDIT: depuis le support 23.1.0, cela n’est plus nécessaire. Voir cette réponse à la place.
Une solution possible consiste à personnaliser le paramètre Behavior
avec votre AppBarLayout
.
<Android.support.design.widget.AppBarLayout
app:layout_behavior="com.myapp.AppBarLayoutSnapBehavior"
Android:layout_width="match_parent"
Android:layout_height="wrap_content">
...
Votre AppBarLayoutSnapBehavior
changerait le comportement par défaut de AppBarLayout.Behavior
, en ajoutant la logique d'accrochage lorsque le défilement s'arrête . Heureusement, le code ci-dessous est explicite.
package com.myapp;
public class AppBarLayoutSnapBehavior extends AppBarLayout.Behavior {
private ValueAnimator mAnimator;
private boolean mNestedScrollStarted = false;
public AppBarLayoutSnapBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child,
View directTargetChild, View target, int nestedScrollAxes) {
mNestedScrollStarted = super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
if (mNestedScrollStarted && mAnimator != null) {
mAnimator.cancel();
}
return mNestedScrollStarted;
}
@Override
public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target) {
super.onStopNestedScroll(coordinatorLayout, child, target);
if (!mNestedScrollStarted) {
return;
}
mNestedScrollStarted = false;
int scrollRange = child.getTotalScrollRange();
int topOffset = getTopAndBottomOffset();
if (topOffset <= -scrollRange || topOffset >= 0) {
// Already fully visible or fully invisible
return;
}
if (topOffset < -(scrollRange / 2f)) {
// Snap up (to fully invisible)
animateOffsetTo(-scrollRange);
} else {
// Snap down (to fully visible)
animateOffsetTo(0);
}
}
private void animateOffsetTo(int offset) {
if (mAnimator == null) {
mAnimator = new ValueAnimator();
mAnimator.setInterpolator(new DecelerateInterpolator());
mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
setTopAndBottomOffset((int) animation.getAnimatedValue());
}
});
} else {
mAnimator.cancel();
}
mAnimator.setIntValues(getTopAndBottomOffset(), offset);
mAnimator.start();
}
}
La seule chose à faire est que la vue de défilement (dans mon cas une RecyclerView
) s'accroche avec la Toolbar
. En fait, j'aime bien ça, mais je ne suis pas sûr que ce soit ce que vous voulez.
Je viens de cacher la disposition de la barre d’action dans l’activité principale et de définir l’étendue de CollapsingToolbarLayout . Cela fonctionne pour moi.
en activité principale
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().hide();
CollapsingToolbarLayout collapsingToolbar =
(CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
collapsingToolbar.setTitle("Name");
loadBackdrop();
et layout_activity_main
<Android.support.design.widget.AppBarLayout
Android:id="@+id/appbar"
Android:layout_width="match_parent"
Android:layout_height="@dimen/detail_backdrop_height"
Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
Android:fitsSystemWindows="true">
<Android.support.design.widget.CollapsingToolbarLayout
Android:id="@+id/collapsing_toolbar"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
app:layout_scrollFlags="scroll|snap"
Android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="48dp"
app:expandedTitleMarginEnd="64dp">
<ImageView
Android:id="@+id/backdrop"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:scaleType="centerCrop"
Android:fitsSystemWindows="true"
app:layout_collapseMode="parallax" />
<Android.support.v7.widget.Toolbar
Android:id="@+id/toolbar"
Android:layout_width="match_parent"
Android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_collapseMode="pin" />
</Android.support.design.widget.CollapsingToolbarLayout>
</Android.support.design.widget.AppBarLayout>