Implementing a Collapsing Toolbar with Android Material Design

Collapsible_final_social

Recently, Mindgrub was tasked with implementing a user profile view in an Android app. This profile view would fill the top of the screen with a profile picture and then collapse into a “normal” toolbar when scrolling to the bottom of the screen.

Here’s an example:

gif example of android

Initially, we were worried that we would have to go out and find a third-party library that implemented this collapsing toolbar (or write it ourselves). Luckily, Google provided developers with the Android Design Support Library, and this kind of animation could be created with new widgets introduced in this library.

 

Here’s the code for an extremely simple demo of this behavior:

<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_layout"
    	android:layout_width="match_parent"
    	android:layout_height="wrap_content">

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

        	<ImageView
            	android:id="@+id/expandedImage"
	            android:layout_width="match_parent"
            	android:layout_height="200dp"
            	android:src="@drawable/beach_scene"

            	android:scaleType="centerCrop"
            	app:layout_collapseMode="parallax"
       	     app:layout_collapseParallaxMultiplier="0.7"
            	/>

        	<android.support.v7.widget.Toolbar
            	android:id="@+id/toolbar"
            	android:layout_width="match_parent"
            	android:layout_height="?attr/actionBarSize"
            	app:layout_collapseMode="pin" >


        	</android.support.v7.widget.Toolbar>


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

	</android.support.design.widget.AppBarLayout>
    <android.support.v4.widget.NestedScrollView
    	android:layout_width="match_parent"
    	android:layout_height="match_parent"
    	android:background="@android:color/white"
    	app:layout_behavior="@string/appbar_scrolling_view_behavior">


        	<TextView
            	android:layout_width="fill_parent"
            	android:layout_height="wrap_content"
            	android:text="@string/sample_string"/>

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

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

Simple, right? Well, maybe not at first glance – but it’s not too difficult to understand once you break it down. Let’s analyze each XML element piece-by-piece:

 

COORDINATORLAYOUT

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

This should be the top-level element in your fragment or activity. The CoordinatorLayout is a new type of element introduced in the Design Library – basically it “coordinates” behavior between its child views. The behavior is specified by attributes set in its child views that are specific to the coordinator layout.

 

APPBARLAYOUT

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

This is another new element from the Design Library that declares a layout for the toolbar. The children of this element will define the behavior of the elements within the Toolbar.

 

AppBarLayouts are actually required to be children of CoordinatorLayouts, and are also required to have a sibling element that has the “layout_behavior” attribute set to “AppBarLayout.ScrollingViewBehavior”. Setting this attribute on the sibling element binds that element to the AppBarLayout, which lets it know when it should scroll. We bind the AppBarLayout to the NestedScrollView, which is discussed further below.

 

COLLAPSINGTOOLBARLAYOUT

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

This element is the child of the “AppBarLayout” and declares the “Collapsing” behavior we want. The children of this element will declare how the toolbar is collapsing.

 

IMAGEVIEW

        	<ImageView
            	android:id="@+id/expandedImage"
	            android:layout_width="match_parent"
            	android:layout_height="200dp"
            	android:src="@drawable/beach_scene"

            	android:scaleType="centerCrop"
            	app:layout_collapseMode="parallax"
       	     app:layout_collapseParallaxMultiplier="0.7"
            	/>

Just a normal ImageView, with a few exceptions: we are setting the “layout_collapseMode” to “parallax”, which causes the ImageView to move as the user scrolls at a specific ratio. You can set this ratio with the (optional) “layout_collapseParallaxMultiplier” setting.

 

TOOLBAR

	<android.support.v7.widget.Toolbar
            	android:id="@+id/toolbar"
            	android:layout_width="match_parent"
            	android:layout_height="?attr/actionBarSize"
            	app:layout_collapseMode="pin" >


        	</android.support.v7.widget.Toolbar>

Again, this is just a normal element you’ve seen before, except for the layout behavior set by the “layout_collapseMode” property. For this element, we are setting it to “pin” which causes it to stick to the top when the user scrolls the view up.

 

NESTEDSCROLLVIEW

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

This is the sibling element to the “AppBarLayout” mentioned above. This is just a normal NestedScrollView, with the exception of the “layout_behavior” attribute set. As mentioned above, setting this attribute binds it to its sibling element, the AppBarLayout.

 

TEXTVIEW

<TextView
            	android:layout_width="fill_parent"
            	android:layout_height="wrap_content"
            	android:text="@string/sample_string"/>

This is simply the scrollable content. This doesn’t have to be a TextView – it can be any kind of layout, RecyclerView, etc. I used a TextView here for simplicity’s sake.

So after understanding all that, you should be all set to implement your own collapsing-toolbar view! Check out the code from our example on Github.