Superposición de vista de desplazamiento con AppBarLayout

103

Quiero implementar el patrón 'Espacio flexible con contenido superpuesto' de las técnicas de desplazamiento de Material design , como en este video : Espacio flexible con contenido superpuesto GIF

Mi diseño XML ahora se ve así:

<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 una manera fácil de lograr esto usando la Biblioteca de diseño? ¿O tengo que crear un CoordinatorLayout.Behavior personalizado para hacer esto?

Ianhanniballake
fuente
Estoy buscando lo opuesto, una imagen dentro de CollapsingToolbarLayout debería mostrar algunos dps más después de la barra de herramientas y debajo de NestedScrollView en otro color.
David
Estaba usando FrameLayout, RelativeLayout pero siempre los fragmentos se superpusieron con actionBar. Usar un NestedScrollView como padre para todos los fragmentos fue la solución. ¡Gracias!
JCarlosR

Respuestas:

148

De hecho, superponer la vista de desplazamiento con AppBarLayout es una característica incluida de la Biblioteca de compatibilidad de diseño de Android : puede usar el app:behavior_overlapTopatributo en su NestedScrollView(o en cualquier Vista que use ScrollingViewBehavior ) para establecer la cantidad de superposición:

<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">

Tenga en cuenta que app:behavior_overlapTopsolo funciona en vistas que tienen el app:layout_behavior="@string/appbar_scrolling_view_behavior"comportamiento que utiliza el atributo (no la Vista ni el Grupo de vistas principal, como se suelen aplicar los atributos), de ahí el behavior_prefijo.

O configúrelo programáticamente a través de setOverlayTop () :

NestedScrollView scrollView = ...
CoordinatorLayout.LayoutParams params = 
    (CoordinatorLayout.LayoutParams) scrollView.getLayoutParams();
AppBarLayout.ScrollingViewBehavior behavior =
    (AppBarLayout.ScrollingViewBehavior) params.getBehavior();
behavior.setOverlayTop(128); // Note: in pixels
Ianhanniballake
fuente
1
Esto casi funciona para mí, excepto que mi RecyclerView (en el que configuré layout_behaviory behavior_overlapTop) termina detrás de su hermano AppBarLayout. Intenté cambiar el orden en el XML, pero no parece tener ningún efecto. ¿Alguna idea de cuál podría ser el problema?
Vicky Chijwani
1
Cuando desactivo el desplazamiento (eliminando los atributos de la aplicación: layout_scrollFlags) - behavior_overlapTop no funciona - NestedScrollView pasa a AppBarLayout. ¿Sabes cómo arreglar ésto?
Pavel Biryukov
@PavelBiryukov, ¿qué hiciste para API <21?
Vicky Chijwani
1
Hola, no me funciona. Reciboerror no resource identifier found for attribute behavior_overlayTop
Jack Lynx
1
@Lynx - bastante confuso, es behavior_overlapToppero setOverlayTop()- superposición vs superposición. ¡Asegúrate de usar el correcto!
ianhanniballake
21

Además de la respuesta aceptada , llame a setTitleEnabled (false) en su CollapsingToolbarLayout para que el título permanezca fijo en la parte superior como en el ejemplo.

Me gusta esto:

CollapsingToolbarLayout.setTitleEnabled(false);

o agregándolo en xml como este:

app:titleEnabled="false"

De lo contrario, el título podría desaparecer detrás del contenido superpuesto, a menos que, por supuesto, ese sea el comportamiento que desea.

G.deWit
fuente
2
Puede poner un título expandidoTitleMarginBottom suficientemente grande en CollapsingToolbarLayout para evitar superponer el título cuando se expande.
WindRider