One of the most amazing things about Design Support Library is that we can create lively animated UIs with some simple configuration in XML. No code nor deep control about scrolls is required, so the process becomes really easy.

We saw that Coordinator Layout is the central point the other components rely on to work properly, and that AppBarLayout helps the toolbar and other components to react to scroll changes. Today, I’ll show you how to use Collapsing Toolbar Layout to create awesome effects in a very easy way.

If you remember, I was changing my MaterializeYourApp repository code to start using the Design Support Library. Today I’ll change the detail screen, and we’ll get something like this:

Collapsing Toolbar Layout

Add a Coordinator Layout

This is the first thing you need. All the new components use a new concept called Behavior that is used by the Coordinator Layout to take some actions based on different interactions.

<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:fitsSystemWindows="true">

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

We’ll be using fitsSystemWindows on any item we want to be painted below the status bar.

Add an App Bar Layout

<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:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        android:fitsSystemWindows="true">

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

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

Nothing difficult here either. We’re setting a dark theme for the AppBarLayout, that way we don’t need to specify to every children that it should use a dark theme.

Add a Collapsing Toolbar Layout

<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:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        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"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleMarginStart="48dp"
            app:expandedTitleMarginEnd="64dp"
            android:fitsSystemWindows="true">

            <com.antonioleiva.materializeyourapp.SquareImageView
                android:id="@+id/image"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                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.design.widget.CoordinatorLayout>

That’s the core part of this article. First, the collapsing layout specify how it will behave when the content is scrolled using the flags scroll|exitUntilCollapsed, so it will scroll until it’s completely collapsed. Then we specify the contentScrim, which is the color the toolbar will take when it reaches it’s collapsed state. I’ll be changing this programmatically and use palette to decide its color. We can also specify the margins for the title when it’s expanded. It will create a nice effect over the toolbar title. You can define some other things, such as the statusScrim or the textAppearance for the collapsed and expanded title.

Inside the layout I added an image, with a parallax collapse mode, and a toolbar, which uses a pin toolbar mode (it will stick to its position).

Add a Nested Scroll View

The rest of the XML just consists of adding a NestedScrollView. It’s an special scroll view which can be inside another scrolling ViewGroup. That way, we can see a continuity when scrolling.

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

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

As you can see, you need to specify this view is the one App Bar will use to decide how to transform its content.

Anchor the Floating Action Button

We can use CoordinatorLayout to anchor some views to others. That’s an extremely useful feature. Besides, FloatingActionButton behavior also will pay attention to AppBarLayout changes, and will hide when it collapses. So another nice effect for free:

<android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        app:layout_anchor="@id/app_bar_layout"
        app:layout_anchorGravity="bottom|right|end"
        style="@style/FabStyle"/>

Nothing else is needed. You can see the complete XML at Github.

Some code tweaks

Now everything should be working, but I added some code that will tint the toolbar using palette, or will help with material transitions.

An important thing to know about the latter point is that we cannot use the image as the transition target. For some reason it won’t work. After trying some different options I found that the one that works best is targeting the AppBarLayout:

ViewCompat.setTransitionName(findViewById(R.id.app_bar_layout), EXTRA_IMAGE);

We also need to set the Collapsing Toolbar Layout title programmatically. I also set the expanded color for the title to transparent, because it was interfering with the transition. Besides, it creates a nice alpha effect:

collapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
        collapsingToolbarLayout.setTitle(itemTitle);
        collapsingToolbarLayout.setExpandedTitleColor(getResources().getColor(android.R.color.transparent));

I’m also tinting the toolbar and the FAB using Palette. I won’t get into details about this, but you can [check the code] (https://github.com/antoniolg/MaterializeYourApp/blob/master/app/src/main/java/com/antonioleiva/materializeyourapp/DetailActivity.java) for more details:

collapsingToolbarLayout.setContentScrimColor(palette.getMutedColor(primary));
collapsingToolbarLayout.setStatusBarScrimColor(palette.getDarkMutedColor(primaryDark));
...
fab.setRippleColor(lightVibrantColor);
fab.setBackgroundTintList(ColorStateList.valueOf(vibrantColor));

Conclusion

With some simple steps, now we have an amazingly animated detail screen that includes most of the things we’ve seen in Material Design specs. We can customize this in many ways really easily, and even manage some more complex effects by creating custom behaviors, which is what we’ll see in next article. You can subscribe to the blog feed to stay tuned.

Author: Antonio Leiva

I’m in love with Kotlin. I’ve been learning about it for a couple of years, applying it to Android and digesting all this knowledge so that you can learn it with no effort.