web-dev-qa-db-ja.com

CoordinatorLayoutの複数のビューにアプリバーのスクロールビューの動作を追加する

CoordinatorLayoutおよびAppBarLayoutとともに、CollapsingToolbarLayoutのスクロール可能な単一の子ビューだけでなく、スクロールサポートを追加したいと考えています。 RecyclerViewまたはAppBarLayout(以下の要約コード)をスクロールすると、アプリバーとそのコンテンツが正常にスクロールして折りたたまれます。ただし、LinearLayoutの上にあるRecyclerViewでスクロールイベントを開始しようとしても、LinearLayoutはビューをスクロールまたは折りたたむことがわからないため、何も起こりません。

目標は、LinearLayoutRecyclerViewへのスティッキーヘッダーとして、またAppBarLayoutへのフッターとして機能させ、RecyclerViewと同じスクロール動作を受け取ることです。 Spotifyのシャッフル再生/利用可能なオフラインヘッダー 。実際、appbar_scrolling_view_behaviorlayout_behaviorLinearLayoutと同様にRecyclerViewに適用できれば素晴らしいのですが、スクロールできない場合は動作が無視されると思いますビュー。 LinearLayoutビューを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>
39
Ryan

いくつかの試行錯誤の後、これは私のために機能するようになったレイアウトの要約版です:

<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"/>
6
Ryan

回避策や奇妙なものは必要ありません。この動作はライブラリでサポートされています。これでLinearLayoutを置き換えて、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>

また、これをRecyclerViewに配置して、LinearLayoutの背後に表示する必要があります。

    Android:paddingTop="30dp"
    Android:clipToPadding="false"

これは次のようになります。

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

これはナイスなデザインではありませんが、解決策です。 Spotifyのようにするには、Layoutの中にもっと良いLinearLayoutを入れることができます。

編集:ビデオが追加されました

Demo videoDemo video 2

46
Mario Velasco

これは、ToolbarRecyclerViewの間にあるスティッキーヘッダーです。

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

Toolbarとの重複を避けるために、AppBarLayoutCollapsingToolbarLayoutに異なる高さを設定できます。

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

ビデオデモ:

Demo video

また、高さをToolbarに設定できますが、このプロジェクト CoordinatorLayoutExample のようなカスタム動作を備えたカスタムタイトルを作成する必要があります。振る舞いのないカスタムタイトルで作成しました。

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

スタイル:

<style name="TransparentText" parent="@Android:style/TextAppearance">
    <item name="Android:textColor">#00000000</item>
</style>

ビデオデモ:

enter image description here

8
Mario Velasco

ライアンのアプローチは優れていますが、少し複雑かもしれません。 CoordinatorLayoutの属性をその子に使用すると、同じ効果を簡単に実現できます。つかいます

layout_anchor="@id/app_bar_layout"

そして

layout_anchorGravity="bottom|right|end"

ビュー(ボタンを含む)でToolbarの下に配置します。また、下にスクロールするとToolbarがビューに重なるため、このビューの標高を上げます。

3
George Kravas

これを試すことができます

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

または

このコードはstrings.xmlで記述できます

<string name="appbar_scrolling_view_behavior" translatable="false">Android.support.design.widget.AppBarLayout$ScrollingViewBehavior</string>

使用できます:

app:layout_behavior="@strings/appbar_scrolling_view_behavior">
3