Superposer la vue de défilement avec AppBarLayout

103

Je souhaite implémenter le modèle `` Espace flexible avec un contenu qui se chevauche '' à partir des techniques de défilement de la conception matérielle , comme dans cette vidéo : Espace flexible avec chevauchement de contenu GIF

Ma mise en page XML ressemble maintenant à:

<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="192dp"
      android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

    <android.support.design.widget.CollapsingToolbarLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">

      <android.support.v7.widget.Toolbar
          android:layout_height="?attr/actionBarSize"
          android:layout_width="match_parent"
          app:layout_collapseMode="pin"/>
    </android.support.design.widget.CollapsingToolbarLayout>
  </android.support.design.widget.AppBarLayout>

  <android.support.v4.widget.NestedScrollView
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
      <....>
    </LinearLayout>
  </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>

Existe-t-il un moyen simple d'accomplir cela en utilisant la bibliothèque de conception? Ou dois-je créer un CoordinatorLayout.Behavior personnalisé pour ce faire?

ianhanniballake
la source
Je recherche l'opposé, une image à l'intérieur de CollapsingToolbarLayout devrait afficher quelques dps de plus après la barre d'outils et sous le NestedScrollView dans une autre couleur!
David
J'utilisais FrameLayout, RelativeLayout mais toujours les fragments se chevauchaient avec l'actionBar. Utiliser un NestedScrollView comme parent pour tous les fragments était la solution. Merci!
JCarlosR

Réponses:

148

En fait, la superposition de la vue de défilement avec AppBarLayout est une fonctionnalité incluse de la bibliothèque de support de conception Android : vous pouvez utiliser l' app:behavior_overlapTopattribut sur votre NestedScrollView(ou toute vue à l'aide de ScrollingViewBehavior ) pour définir le montant de chevauchement:

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    app:behavior_overlapTop="64dp">

Notez que cela app:behavior_overlapTopne fonctionne que sur les vues qui ont app:layout_behavior="@string/appbar_scrolling_view_behavior"comme c'est le comportement qui utilise l'attribut (pas la vue ou le groupe de vues parent, comme les attributs s'appliquent généralement), d'où le behavior_préfixe.

Ou définissez-le par programme via setOverlayTop () :

NestedScrollView scrollView = ...
CoordinatorLayout.LayoutParams params = 
    (CoordinatorLayout.LayoutParams) scrollView.getLayoutParams();
AppBarLayout.ScrollingViewBehavior behavior =
    (AppBarLayout.ScrollingViewBehavior) params.getBehavior();
behavior.setOverlayTop(128); // Note: in pixels
ianhanniballake
la source
1
Cela fonctionne presque pour moi, sauf que mon RecyclerView (sur lequel j'ai défini le layout_behavioret behavior_overlapTop) se termine derrière son frère AppBarLayout. J'ai essayé de changer l'ordre dans le XML, mais cela ne semble pas avoir d'effet. Des idées sur quel pourrait être le problème?
Vicky Chijwani
1
Lorsque je désactive le défilement (suppression des attributs app: layout_scrollFlags) - behavior_overlapTop ne fonctionne pas - NestedScrollView passe sous AppBarLayout. Savez-vous comment résoudre ce problème?
Pavel Biryukov
@PavelBiryukov qu'avez-vous fait pour API <21?
Vicky Chijwani
1
Bonjour, ça ne marche pas pour moi. Je reçoiserror no resource identifier found for attribute behavior_overlayTop
Jack Lynx
1
@Lynx - assez déroutant, c'est behavior_overlapTopmais setOverlayTop()- chevauchement vs superposition. Assurez-vous que vous utilisez le bon!
ianhanniballake
21

En plus de la réponse acceptée , appelez setTitleEnabled (false) sur votre CollapsingToolbarLayout pour que le titre reste fixe en haut comme dans l'exemple.

Comme ça:

CollapsingToolbarLayout.setTitleEnabled(false);

ou en l'ajoutant en xml comme ceci:

app:titleEnabled="false"

Sinon, le titre pourrait disparaître derrière le contenu qui se chevauchent, à moins bien sûr que ce soit le comportement que vous souhaitez.

G.deWit
la source
2
Vous pouvez placer un ExpandTitleMarginBottom suffisamment grand dans CollapsingToolbarLayout pour éviter de chevaucher le titre lorsqu'il est développé.
WindRider