Android Collapsing Toolbar With Parallax Image

Toolbar expand with image background when scroll down.

First, create a Scrolling Activity in Android Studio. File -> New -> Activity -> Scrolling Activity.

Add Scrolling Activity

The Scrolling Activity comes with CollapsingToolbarLayout, FloatingActionButton and NestedScrollView. Now we have:

  • Scrollable content
  • A toolbar/appbar which can expand/collapse based on scroll down/up
  • A FloatingActionButton which hide on scroll up and shown on scroll down

Next, we want to add an image into CollapsingToolbarLayout.

Copy an image into res/drawable. One of the way is Copy the image file (Ctrl-C or Right Click -> Copy), right click on res/drawable and click Paste.

  • In Choose Destination Directory, select drawable (assuming you are using JPG or PNG)
  • In Copy, give it a New name and click OK

NOTE: try to limit the image size to 1200px, else there is a high chances of OutOfMemoryError.

NOTE: for vector/svg image, use File -> New -> Vector Asset -> Asset Type: Local file

Import Image Directory

Import Image Copy

We need to make a few changes to CollapsingToolbarLayout.

  • Change CollapsingToolbarLayout app:expandedTitleGravity="top". This is to make sure the toolbar title stay on top when collapsing toolbar is expanded.
  • We add ImageView and TextView within CollapsingToolbarLayout.
  • For ImageView, set android:scaleType="centerCrop" to prevent squished image and set app:layout_collapseMode="parallax"
  • For TextView (serve at secondary text at bottom), set app:layout_collapseMode="parallax" and android:layout_gravity="bottom"

NOTE: remember to use ImageView android:src to set image, not android:background (else the background shall be stretch to fit)

<android.support.design.widget.CollapsingToolbarLayout
    android:id="@+id/toolbar_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    app:contentScrim="?attr/colorPrimary"
    app:layout_scrollFlags="scroll|exitUntilCollapsed"
    app:expandedTitleGravity="top"
    app:toolbarId="@+id/toolbar">

    <ImageView
        android:id="@+id/header"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/bg_coffee_1200"
        android:fitsSystemWindows="true"
        android:scaleType="centerCrop"
        app:layout_collapseMode="parallax" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="16sp"
        android:textColor="@android:color/white"
        android:layout_marginLeft="32dp"
        android:layout_marginStart="32dp"
        android:layout_marginBottom="32dp"
        android:layout_marginEnd="32dp"
        app:layout_collapseMode="parallax"
        android:layout_gravity="bottom"
        android:text="Like LuaPass?\nBuy me a coffee :)"/>

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

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

Android Toolbar Parallax

Below is the full code.

Activity

class ScrollingActivity : AppCompatActivity() {    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_scrolling)        setSupportActionBar(toolbar)        fab.setOnClickListener { view ->            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)                    .setAction("Action", null).show()        }    }    override fun onCreateOptionsMenu(menu: Menu): Boolean {        // Inflate the menu; this adds items to the action bar if it is present.        menuInflater.inflate(R.menu.menu_scrolling, menu)        return true    }    override fun onOptionsItemSelected(item: MenuItem): Boolean {        // Handle action bar item clicks here. The action bar will        // automatically handle clicks on the Home/Up button, so long        // as you specify a parent activity in AndroidManifest.xml.        return when (item.itemId) {            R.id.action_settings -> true            else -> super.onOptionsItemSelected(item)        }    }}

activity.xml

<?xml version="1.0" encoding="utf-8"?>
<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:fitsSystemWindows="true"
    tools:context=".ScrollingActivity">

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

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:expandedTitleGravity="top"
            app:toolbarId="@+id/toolbar">

            <ImageView
                android:id="@+id/header"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@drawable/coffee_1200"
                android:fitsSystemWindows="true"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="16sp"
                android:textColor="@android:color/white"
                android:layout_marginLeft="32dp"
                android:layout_marginStart="32dp"
                android:layout_marginBottom="32dp"
                android:layout_marginEnd="32dp"
                app:layout_collapseMode="parallax"
                android:layout_gravity="bottom"
                android:text="Like LuaPass?\nBuy me a coffee :)"/>

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

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

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

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/fab_margin"
        app:layout_anchor="@id/app_bar"
        app:layout_anchorGravity="bottom|end"
        app:srcCompat="@android:drawable/ic_dialog_email" />

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

content.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView 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"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".ScrollingActivity"
    tools:showIn="@layout/activity_scrolling">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/text_margin"
        android:text="@string/large_text" />

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

❤️ Is this article helpful?

Buy me a coffee ☕ or support my work via PayPal to keep this space 🖖 and ad-free.

Do send some 💖 to @d_luaz or share this article.

✨ By Desmond Lua

A dream boy who enjoys making apps, travelling and making youtube videos. Follow me on @d_luaz

👶 Apps I built

Travelopy - discover travel places in Malaysia, Singapore, Taiwan, Japan.