Je souhaite ajouter la prise en charge du défilement à plus d’une vue enfant unique et défilable de CoordinatorLayout
conjointement avec un AppBarLayout
et CollapsingToolbarLayout
. Lorsque vous faites défiler le RecyclerView
ou le AppBarLayout
(code condensé ci-dessous), la barre d’applications et son contenu défilent et se replient avec succès. Cependant, lorsque vous tentez d'initier un événement de défilement sur le LinearLayout
au-dessus de RecyclerView
, rien ne se produit car le LinearLayout
ne sait pas faire défiler ou réduire la vue.
Le but est que le LinearLayout
agisse comme un en-tête collant pour le RecyclerView
et le pied de page pour le AppBarLayout
et reçoive le même comportement de défilement que le RecyclerView
, semblable à lecture aléatoire de Spotify/en-tête hors connexion disponible . En fait, ce serait bien si le appbar_scrolling_view_behavior
layout_behavior
pourrait être appliqué au LinearLayout
de la même façon que le RecyclerView
, mais j'imagine que le comportement est ignoré sur les vues non défilables. Quelqu'un a-t-il connaissance d'une solution de contournement pour cela qui n'exige pas la mise en place de la vue LinearLayout
sous la forme d'une ligne dans le RecyclerView
?
<Android.support.design.widget.CoordinatorLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<Android.support.design.widget.AppBarLayout
Android:id="@+id/app_bar_layout"
Android:layout_width="match_parent"
Android:layout_height="@dimen/collapsible_app_bar_height"
Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<Android.support.design.widget.CollapsingToolbarLayout
Android:id="@+id/collapsing_toolbar_layout"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:background="@drawable/gradient_banner"
app:contentScrim="@color/background_content_frame"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
Android:id="@+id/image_header"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:src="@drawable/some_image"
app:layout_collapseMode="parallax"/>
<Android.support.v7.widget.Toolbar
Android:id="@+id/collapsible_toolbar"
Android:layout_width="match_parent"
Android:layout_height="?attr/actionBarSize"
Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_collapseMode="pin"/>
</Android.support.design.widget.CollapsingToolbarLayout>
</Android.support.design.widget.AppBarLayout>
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="@dimen/slide_handle_height"
Android:orientation="horizontal"
Android:background="@color/slide_handle"
Android:gravity="center_vertical">
<!-- three buttons -->
</LinearLayout>
<Android.support.v7.widget.RecyclerView
Android:id="@+id/recycler_view"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_marginTop="@dimen/slide_handle_height"
Android:scrollbars="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</Android.support.design.widget.CoordinatorLayout>
Après quelques essais et erreurs, voici la version condensée de la présentation qui a finalement fonctionné pour moi:
<Android.support.design.widget.CoordinatorLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
xmlns:tools="http://schemas.Android.com/tools"
Android:id="@+id/coordinator_layout"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<Android.support.design.widget.AppBarLayout
Android:id="@+id/app_bar_layout"
Android:layout_width="match_parent"
Android:layout_height="@dimen/collapsible_app_bar_height"
Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<Android.support.design.widget.CollapsingToolbarLayout
Android:id="@+id/collapsing_toolbar_layout"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
app:contentScrim="@color/background_content_frame"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
Android:id="@+id/image_header"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_gravity="center_horizontal"
Android:layout_marginBottom="@dimen/button_bar_height"
Android:scaleType="centerCrop"
Android:background="@Android:color/transparent"
Android:src="@drawable/default_header"
Android:contentDescription="@string/description_content_image"
app:layout_collapseMode="parallax"/>
<ImageView
Android:id="@+id/image_header_gradient"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_marginBottom="@dimen/button_bar_height"
Android:src="@drawable/scrim_top_bottom_banner"
app:layout_collapseMode="parallax"
tools:ignore="ContentDescription"/>
<Android.support.v7.widget.Toolbar
Android:id="@+id/collapsible_toolbar"
Android:layout_width="match_parent"
Android:layout_height="104dp"
Android:minHeight="?attr/actionBarSize"
Android:gravity="top"
Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:contentInsetStart="0dp"
app:titleMargins="0dp"
app:layout_collapseMode="pin"/>
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_marginStart="@dimen/landing_header_button_margin_horizontal"
Android:layout_marginEnd="@dimen/landing_header_button_margin_horizontal"
Android:layout_marginBottom="@dimen/button_bar_height"
Android:layout_gravity="bottom"
Android:gravity="center_vertical"
app:layout_collapseMode="parallax">
<Button
Android:id="@+id/button_one"
Android:layout_alignParentStart="true"
Android:drawableStart="@drawable/selector_one"
Android:textColor="@color/alabaster_white"
Android:visibility="gone"
style="@style/Button.TextCount"/>
<Button
Android:id="@+id/button_two"
Android:layout_alignParentEnd="true"
Android:layout_gravity="end"
Android:drawableStart="@drawable/selector_two"
Android:textColor="@color/alabaster_white"
Android:visibility="gone"
style="@style/Button.TextCount"/>
</RelativeLayout>
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="@dimen/button_bar_height"
Android:layout_gravity="bottom"
Android:gravity="center_vertical"
Android:orientation="horizontal"
Android:background="@color/slide_handle">
<!-- three buttons -->
</LinearLayout>
</Android.support.design.widget.CollapsingToolbarLayout>
</Android.support.design.widget.AppBarLayout>
<Android.support.v7.widget.RecyclerView
Android:id="@+id/recycler_view"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:scrollbars="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
Vous n'avez pas besoin d'une solution de contournement ou de quelque chose d'étrange. Ce comportement est pris en charge par la bibliothèque. Il suffit de remplacer votre LinearLayout
par ceci et de le placer sous le RecyclerView
:
<Android.support.v4.widget.NestedScrollView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="vertical"
Android:gravity="center">
<Button
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:padding="15dp"
Android:text="Button text"/>
</LinearLayout>
</Android.support.v4.widget.NestedScrollView>
Aussi, vous devrez mettre ceci dans votre RecyclerView
pour le montrer derrière LinearLayout:
Android:paddingTop="30dp"
Android:clipToPadding="false"
Voici à quoi cela ressemblerait:
<Android.support.design.widget.CoordinatorLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<Android.support.design.widget.AppBarLayout
Android:id="@+id/app_bar_layout"
Android:layout_width="match_parent"
Android:layout_height="@dimen/collapsible_app_bar_height"
Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<Android.support.design.widget.CollapsingToolbarLayout
Android:id="@+id/collapsing_toolbar_layout"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:background="@drawable/gradient_banner"
app:contentScrim="@color/background_content_frame"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
Android:id="@+id/image_header"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:src="@drawable/some_image"
app:layout_collapseMode="parallax"/>
<Android.support.v7.widget.Toolbar
Android:id="@+id/collapsible_toolbar"
Android:layout_width="match_parent"
Android:layout_height="?attr/actionBarSize"
Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_collapseMode="pin"/>
</Android.support.design.widget.CollapsingToolbarLayout>
</Android.support.design.widget.AppBarLayout>
<Android.support.v7.widget.RecyclerView
Android:id="@+id/recycler_view"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_marginTop="@dimen/slide_handle_height"
Android:scrollbars="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
Android:paddingTop="30dp"
Android:clipToPadding="false"/>
<Android.support.v4.widget.NestedScrollView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="vertical"
Android:gravity="center">
<Button
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:padding="15dp"
Android:text="Button text"/>
</LinearLayout>
</Android.support.v4.widget.NestedScrollView>
</Android.support.design.widget.CoordinatorLayout>
Ce n'est pas un beau design, mais c'est une solution. Vous pouvez placer un Layout
plus agréable à l'intérieur du LinearLayout
pour qu'il ressemble à Spotify.
Edit: Vidéo ajoutée
Ceci est un en-tête collant placé au milieu entre Toolbar
et RecyclerView
:
<Button
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
app:layout_anchor="@+id/app_bar_layout"
app:layout_anchorGravity="center|bottom"
Android:text="Shuffle Play"/>
Pour éviter les chevauchements avec le Toolbar
, vous pouvez définir différentes hauteurs sur AppBarLayout
et CollapsingToolbarLayout
:
<Android.support.design.widget.CoordinatorLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:id="@+id/main_content"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fitsSystemWindows="true">
<Android.support.design.widget.AppBarLayout
Android:id="@+id/appbar"
Android:layout_width="match_parent"
Android:layout_height="240dp"
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="210dip"
Android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
Android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="48dp"
app:expandedTitleMarginBottom="30dp"
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>
<Android.support.v7.widget.RecyclerView
Android:id="@+id/recycler_view"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_marginTop="@dimen/slide_handle_height"
Android:scrollbars="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
<Button
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="center|bottom"
Android:text="Shuffle Play"/>
</Android.support.design.widget.CoordinatorLayout>
Démo vidéo:
En outre, vous pouvez définir une hauteur sur Toolbar
mais vous devrez créer un titre personnalisé avec un comportement personnalisé tel que ce projet CoordinatorLayoutExample . Je l'ai fait avec un titre personnalisé sans comportement:
<Android.support.design.widget.CoordinatorLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:id="@+id/main_content"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fitsSystemWindows="true">
<Android.support.design.widget.AppBarLayout
Android:id="@+id/appbar"
Android:layout_width="match_parent"
Android:layout_height="240dp"
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"
Android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
Android:fitsSystemWindows="true"
app:collapsedTitleTextAppearance="@style/TransparentText"
app:expandedTitleTextAppearance="@style/TransparentText"
app:contentScrim="?attr/colorPrimary">
<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_height="80dp"
Android:layout_width="match_parent"
Android:minHeight="?attr/actionBarSize"
Android:gravity="top"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_collapseMode="pin" >
<TextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="Title"
Android:textSize="20sp"
Android:textColor="@Android:color/white"/>
</Android.support.v7.widget.Toolbar>
</Android.support.design.widget.CollapsingToolbarLayout>
</Android.support.design.widget.AppBarLayout>
<Android.support.v7.widget.RecyclerView
Android:id="@+id/recycler_view"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_marginTop="@dimen/slide_handle_height"
Android:scrollbars="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
<Button
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="center|bottom"
Android:text="Shuffle Play"/>
</Android.support.design.widget.CoordinatorLayout>
Modes:
<style name="TransparentText" parent="@Android:style/TextAppearance">
<item name="Android:textColor">#00000000</item>
</style>
Démo vidéo:
L'approche de Ryan est bonne mais peut-être un peu compliquée. Vous pouvez obtenir le même effet plus facilement en utilisant les attributs de CoordinatorLayout
pour ses enfants. Utilisation
layout_anchor="@id/app_bar_layout"
et
layout_anchorGravity="bottom|right|end"
dans une vue (contenant vos boutons) et placez-le sous le Toolbar
. Augmentez également l’altitude de cette vue car, lorsque vous faites défiler l'écran, Toolbar
chevauchera votre vue.
Tu peux essayer ça
<Android.support.design.widget.CoordinatorLayout>
<Android.support.design.widget.AppBarLayout>
<!-- another xml code -->
</<Android.support.design.widget.AppBarLayout>
<Android.support.v4.widget.NestedScrollView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
app:layout_behavior="Android.support.design.widget.AppBarLayout$ScrollingViewBehavior">
<!-- your recyler view or button or textview xml code -->
</Android.support.v4.widget.NestedScrollView>
</Android.support.design.widget.CoordinatorLayout>
ou
vous pouvez écrire ce code en strings.xml
<string name="appbar_scrolling_view_behavior" translatable="false">Android.support.design.widget.AppBarLayout$ScrollingViewBehavior</string>
et vous pouvez utiliser:
app:layout_behavior="@strings/appbar_scrolling_view_behavior">