CollapsingToolbarLayout expand only when at the top
I ended up moving the orange bar out of the CollapsingToolbarLayout
and setting an OnOffsetChangedListener
that changes the translationY
of the top bar on the AppBarLayout
.
Setting the OnOffsetChangedListener
:
app_bar.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appbar, offset ->
topbar.translationY = Math.min(image.height.toFloat(), - offset.toFloat())
})
Layout:
<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>
There are lots of effects on the scrolling behavior that can be achieved by setting different layout_scrollFlags
. In your case, I think the flag you want is enterAlwaysCollapsed
. Add the flag along with enterAlways
instead of replacing all the flags.
scroll
will make the toolbar scroll like the rest of the content, enterAlways
will make the toolbar AND the rest of the CollapsingToolbarLayout
to pop back immediately after scroll up, whereas enterAlwaysCollapsed
only expands the CollapsingToolbarLayout
after the page is scrolled all the way to the top.
Here's the effect that enterAlwaysCollapsed
achieves.
Customisation of CoordinatorLayout
behaviour is hard. You want the orange bar to appear immediately but ImageView only after the content is scrolled to the top, but these views belong to one parent CollapsingToolbarLayout
and both get either the behaviour you have now or the opposite with enterAlwaysCollapsed
flag. I see no way to separate the behaviour for these views without messing with CoordinatorLayout/CollapsingToolbarLayout Java API.
If simpler behaviour is not an option and noone here points out a simple solution, I suggest trying a relatively new MotionLayout
instead of dancing with CollapsingToolbarLayout
internals, you will save yourself a lot of time in the end. It will be a little harder at start but it provides clear ways for customisation. Here's a very good article that shows how to build a UX similar to CoordinatorLayout
but using MotionLayout
. And the second part of this article with some additional customisations.