CollapsingToolbarLayout 仅在顶部展开

CollapsingToolbarLayout expand only when at the top

我在使用 AppBarLayout 和 CollapsingToolbarLayout 时遇到一些问题。这是当前发生的情况:

https://www.youtube.com/watch?v=z4yD8rmjSjU

向下滚动的动作正是我想要的。然而,当我再次向上滚动时,橙色条应该立即出现(确实如此),但我希望 ImageView 仅在用户滚动到最顶部时才开始出现。谁能帮我实现这个效果?

这是我的布局xml:

<android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

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

        <TextView
                android:text="ImageView"
                android:textSize="20sp"
                android:textColor="@android:color/white"
                android:gravity="center"
                android:layout_marginTop="56dp"
                android:layout_width="match_parent"
                android:layout_height="145dp"
                app:layout_collapseMode="parallax"
                android:background="#444"/>

        <TextView
                android:text="Top bar"
                android:textColor="@android:color/white"
                android:gravity="center_vertical"
                android:paddingStart="16dp"
                android:paddingEnd="16dp"
                android:layout_width="match_parent"
                android:layout_height="56dp"
                android:background="#ff8000"
                app:layout_collapseMode="pin"/>

    </android.support.design.widget.CollapsingToolbarLayout>

    <TextView
            android:text="Bottom bar"
            android:gravity="center_vertical"
            android:paddingStart="16dp"
            android:paddingEnd="16dp"
            android:layout_width="match_parent"
            android:textColor="@android:color/black"
            android:layout_height="50dp"
            android:background="#ddd"
            app:layout_scrollFlags="enterAlways"/>


</android.support.design.widget.AppBarLayout>

<include layout="@layout/content_scrolling"/>

通过设置不同的 layout_scrollFlags 可以实现对滚动行为的许多影响。在你的情况下,我认为你想要的标志是 enterAlwaysCollapsed。将标志与 enterAlways 一起添加,而不是替换所有标志。

scroll 将使工具栏像其余内容一样滚动,enterAlways 将使工具栏和 CollapsingToolbarLayout 的其余部分在向上滚动后立即弹出,而enterAlwaysCollapsed 仅在页面一直滚动到顶部后展开 CollapsingToolbarLayout

Here就是enterAlwaysCollapsed达到的效果

CoordinatorLayout 行为的自定义很难。您希望橙色条立即出现,但 ImageView 仅在内容滚动到顶部后才出现,但这些视图属于一个父级 CollapsingToolbarLayout 并且都得到 either 您的行为现在 enterAlwaysCollapsed 标志相反。我认为没有办法在不弄乱 CoordinatorLayout/CollapsingToolbarLayout Java API.

的情况下分离这些视图的行为

如果更简单的行为不是一个选项并且这里没有人指出一个简单的解决方案,我建议尝试一个相对较新的 MotionLayout 而不是与 CollapsingToolbarLayout 内部一起跳舞,你会节省很多时间到底。开始时会有点困难,但它提供了清晰的定制方式。这是 a very good article that shows how to build a UX similar to CoordinatorLayout but using MotionLayout. And the second part of this article 以及一些额外的自定义设置。

我认为你可以通过你的代码来管理它,我已经通过简单地检测布局行为来尝试过

 app_bar.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
    @Override
    public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {

        if (Math.abs(verticalOffset)-appBarLayout.getTotalScrollRange() == 0)
        {
            //  Collapsed


        }
        else
        {
            //Expanded


        }
    }
});

试试这个@Mark.I 得到了你在视频中展示的卷轴

<android.support.design.widget.CoordinatorLayout 
 xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
    android:id="@+id/app_bar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

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

        <TextView
            android:layout_width="match_parent"
            android:layout_height="145dp"
            android:layout_marginTop="56dp"
            android:background="#444"
            android:gravity="center"
            android:text="ImageView"
            android:textColor="@android:color/white"
            android:textSize="20sp"
            app:layout_collapseMode="parallax" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="56dp"
            android:background="#ff8000"
            android:gravity="center_vertical"
            android:paddingStart="16dp"
            android:paddingEnd="16dp"
            android:text="Top bar"
            android:textColor="@android:color/white"
            app:layout_collapseMode="pin" />

    </android.support.design.widget.CollapsingToolbarLayout>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#ddd"
        android:gravity="center_vertical"
        android:paddingStart="16dp"
        android:paddingEnd="16dp"
        android:text="Bottom bar"
        android:textColor="@android:color/black"
        app:layout_scrollFlags="enterAlways" />
</android.support.design.widget.AppBarLayout>


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

    <include layout="@layout/content_scrolling"/>

</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>

我最终将橙色栏移出 CollapsingToolbarLayout 并设置了一个 OnOffsetChangedListener 来更改 AppBarLayout 顶部栏的 translationY

设置 OnOffsetChangedListener:

app_bar.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appbar, offset ->

    topbar.translationY = Math.min(image.height.toFloat(),  - offset.toFloat())

})

布局:

<android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

    <TextView
            android:layout_width="match_parent"
            android:layout_height="56dp"
            android:id="@+id/topbar"
            app:elevation="8dp"
            android:elevation="8dp"
            android:background="#ff8000"
            android:gravity="center_vertical"
            android:paddingStart="16dp"
            android:paddingEnd="16dp"
            android:text="Top bar"
            android:textColor="@android:color/white"
            app:layout_scrollFlags="scroll|enterAlways" />

    <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/image"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed">

        <TextView
                android:layout_width="match_parent"
                android:layout_height="145dp"
                android:background="#444"
                android:gravity="center"
                android:text="ImageView"
                android:textColor="@android:color/white"
                android:textSize="20sp"
                app:layout_collapseMode="parallax" />


    </android.support.design.widget.CollapsingToolbarLayout>

    <TextView
            android:id="@+id/bottombar"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            app:elevation="8dp"
            android:elevation="8dp"
            android:background="#ddd"
            android:gravity="center_vertical"
            android:paddingStart="16dp"
            android:paddingEnd="16dp"
            android:text="Bottom bar"
            android:textColor="@android:color/black"
            app:layout_scrollFlags="enterAlways" />
</android.support.design.widget.AppBarLayout>

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

    <include layout="@layout/content_scrolling"/>

</android.support.v4.widget.NestedScrollView>