La bibliothèque de support de conception v. 23.2
A introduit BottomSheetBehavior
, qui permet aux enfants d'un coordinateur d'agir comme des feuilles inférieures (vues déplaçables depuis le bas de l'écran).
Ce que je voudrais faire, c'est d'avoir, comme vue de bas de page , la vue suivante (le coordinateur typique + les choses qui se réduisent):
<CoordinatorLayout
app:layout_behavior=“@string/bottom_sheet_behavior”>
<AppBarLayout>
<CollapsingToolbarLayout>
<ImageView />
</CollapsingToolbarLayout>
</AppBarLayout>
<NestedScrollView>
<LinearLayout>
< Content ... />
</LinearLayout>
</NestedScrollView>
</CoordinatorLayout>
Malheureusement, les vues de la feuille inférieure doivent implémenter le défilement imbriqué, sinon elles n'obtiendront pas d'événements de défilement. Si vous essayez avec une activité principale, puis chargez cette vue en tant que feuille inférieure, vous verrez que les événements de défilement n'agissent que sur la "feuille" de papier, avec un comportement étrange, comme vous pouvez le voir si vous continuez à lire.
Je suis sûr que cela peut être géré en sous-classant CoordinatorLayout
, ou mieux encore en sous-classant BottomSheetBehavior
. Avez-vous un indice?
requestDisallowInterceptTouchEvent()
doit être utilisé pour voler des événements au parent dans certaines conditions:
AppBarLayout
est> 0AppBarLayout
est == 0, mais nous faisons défiler vers le haut (pensez-y une seconde et vous verrez)la première condition peut être obtenue en définissant un OnOffsetChanged
dans la barre d'application interne;
la seconde nécessite une gestion des événements, par exemple:
switch (MotionEventCompat.getActionMasked(event)) {
case MotionEvent.ACTION_DOWN:
startY = event.getY();
lastY = startY;
userIsScrollingUp = false;
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
userIsScrollingUp = false;
break;
case MotionEvent.ACTION_MOVE:
lastY = event.getY();
float yDeltaTotal = startY - lastY;
if (yDeltaTotal > touchSlop) { // Moving the finger up.
userIsScrollingUp = true;
}
break;
}
Inutile de dire que je ne peux pas faire fonctionner ça maintenant. Je ne suis pas en mesure d'attraper les événements lorsque les conditions sont remplies, et de ne pas les attraper dans d'autres cas. Dans l'image ci-dessous, vous pouvez voir ce qui se passe avec un coordinateur standard.
La feuille est ignorée si vous faites défiler vers le bas sur la barre d'applications, mais pas si vous faites défiler vers le bas le contenu imbriqué. Il semble que les événements de défilement imbriqués ne se propagent pas au comportement du coordinateur;
Il y a également un problème avec la barre d'applications interne: le contenu du défilement imbriqué ne suit pas la barre d'applications lorsqu'elle est réduite.
J'ai configuré un exemple de projet sur github qui montre ces problèmes.
Comportement correct des barres d'applications/vues de défilement à l'intérieur de la feuille;
Lorsque la feuille est développée, elle peut s'effondrer lors du défilement vers le bas, mais uniquement si la barre d'application interne est également entièrement développée . À l'heure actuelle, il s'effondre sans égard à l'état de la barre d'applications, et uniquement si vous faites glisser la barre d'applications;
Lorsque la feuille est réduite, les gestes de défilement vers le haut la développent (sans effet sur la barre d’applications interne).
Un exemple de l'application contacts (qui n'utilise probablement pas BottomSheetBehavior, mais c'est ce que je veux):
J'ai finalement publié mon implémentation. Trouvez-le sur Github ou directement depuis jcenter:
compile 'com.otaliastudios:bottomsheetcoordinatorlayout:1.0.0’
Tout ce que vous avez à faire est d'utiliser BottomSheetCoordinatorLayout
comme vue racine de votre feuille inférieure. Il se gonflera automatiquement un comportement de travail, alors ne vous inquiétez pas.
Je l'utilise depuis longtemps et cela ne devrait pas avoir de problèmes de défilement, prend en charge le glissement sur l'ABL, etc.
Je viens de suivre la façon dont vous avez posé la question ci-dessus et de trouver une solution qui pourrait nécessiter plus d'explications.S'il vous plaît suivez votre exemple de code et intégrez la partie supplémentaire dans votre xml pour le faire se comporter comme le comportement BottomSheeet
<CoordinatorLayout>
<AppBarLayout>
<Toolbar
app:layout_collapseMode="pin">
</Toolbar>
</AppBarLayout>
<NestedScrollView
app:layout_behavior=“@string/bottom_sheet_behavior” >
<include layout="@layout/items" />
</NestedScrollView>
<!-- Bottom Sheet -->
<BottomSheetCoordinatorLayout>
<AppBarLayout
<CollapsingToolbarLayout">
<ImageView />
<Toolbar />
</CollapsingToolbarLayout>
</AppBarLayout>
<NestedScrollView">
<include layout="@layout/items" />
</NestedScrollView>
</BottomSheetCoordinatorLayout>
</CoordinatorLayout>
Remarque: Solution qui a fonctionné pour moi déjà expliquée dans le dernier commentaire de votre question
Meilleure explication: https://github.com/laenger/BottomSheetCoordinatorLayout
Essayez de ne pas utiliser NestedScrollView
avec LinearLayout
, cela a également causé des problèmes dans mon application. Utilisez simplement LinearLayout
à la place, cela me convient.
Essayez ce qui suit:
<CoordinatorLayout
app:layout_behavior=“@string/bottom_sheet_behavior”>
<AppBarLayout>
<CollapsingToolbarLayout>
<ImageView />
</CollapsingToolbarLayout>
</AppBarLayout>
<LinearLayout>
<!--don't forget to addd this line-->
app:layout_behavior="@string/appbar_scrolling_view_behavior">
< Content ... />
</LinearLayout>
j'ai suivi le projet de test github initial de Laenger concernant ce problème, et je suis heureux de vous partager une solution pour certains de ses problèmes, car j'avais également besoin de ce comportement dans mon application.
c'est une solution à son problème: bar la barre d'outils s'effondre parfois trop tôt
pour éviter cela, vous devez créer votre AppBarLayout.Behavior
personnalisé, car c'est lorsque vous faites défiler vers le haut tout en faisant glisser que le AppBarLayout.behavior
obtient le mouvement de défilement. Nous devons détecter si c'est dans STATE_DRAGGING et simplement revenir pour éviter de masquer/réduire la barre d'outils prématurément.
public class CustomAppBarLayoutBehavior extends AppBarLayout.Behavior {
private CoordinatorLayoutBottomSheetBehavior behavior;
public CustomAppBarLayoutBehavior() {
}
public CustomAppBarLayoutBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes) {
behavior = CoordinatorLayoutBottomSheetBehavior.from(parent);
return super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes);
}
@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed) {
if(behavior.getState() == CoordinatorLayoutBottomSheetBehavior.STATE_DRAGGING){
return;
}else {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
}
}
@Override
public void setDragCallback(@Nullable DragCallback callback) {
super.setDragCallback(callback);
}
}
cela peut être un bon début pour résoudre les autres problèmes:
Bar la barre d'outils ne peut pas être réduite par des traînées
Layout La disposition du coordinateur principal consomme du défilement
je ne suis pas vraiment une bonne personne en UI/animation, mais le travail acharné rapporte parfois la compréhension du code, en trouvant la bonne fonction de rappel/remplacement à implémenter.
définissez ce comportement sur appbarlayout
<Android.support.design.widget.AppBarLayout
Android:id="@+id/bottom_sheet_appbar"
style="@style/BottomSheetAppBarStyle"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
app:layout_behavior="your.package.CustomAppBarLayoutBehavior">
Si le premier enfant est nestedscroll
, cela entraînera d'autres problèmes. Cette solution est corrigée mon problème j'espère aussi résoudre le vôtre.
<CoordinatorLayout
app:layout_behavior=“@string/bottom_sheet_behavior”>
<AppBarLayout>
<CollapsingToolbarLayout>
<ImageView />
</CollapsingToolbarLayout>
</AppBarLayout>
</LinearLayout>
<NestedScrollView>
<LinearLayout>
< Content ... />
</LinearLayout>
</NestedScrollView>
</LinearLayout>
</CoordinatorLayout>