Android Collapsing Toolbar With Image

Scrolling activity with image android

Android Collapsing Toolbar With Image

This pattern of Collapsing Toolbar Layout is a popular scrolling technique. In familiar terms, you can see this on several apps with a profile detail screen. Android CollapsingToolbarLayout is a wrapper for Toolbar which implements a collapsing app bar. It is designed to be used as a direct child of an AppBarLayout.

You can see the Toolbar dynamically changes color, depending on the image. It takes on the most dominant color present in the image. This is a scrolling technique that supports an image header with a scrollable view below it.

This layout consists of:

  • Collapsing Title: The title is larger when the layout is expanded. The text size becomes smaller as the layout is collapsed and scrolled off the screen.
  • app:layout_scrollFlags: The scroll flags of this layout is typically set to “scroll|exitUntilCollapsed”.
  • app:collapsedTitleGravity: Specifies the gravity of title in the container when collapsed.
  • app:contentScrim: This requires specifying a drawable or color value of the CollapsingToolbarLayouts content when it has been scrolled sufficiently off screen eg. ?attr/colorPrimary.
  • app:scrimAnimationDuration: Specifies the duration used for scrim visibility animations. This requires an integer value.

 

Getting Started

Start by adding the Design Support Library to your app/build.gradle file.

dependencies { 
    … 
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'com.google.android.material:material:1.0.0'
}

Layout Structure

As always, we’ll get started with the XML first. Open your activity.xml layout.

Here’s the layout skeleton.

<androidx.coordinatorlayout.widget.CoordinatorLayout >

    <com.google.android.material.appbar.AppBarLayout >

        <com.google.android.material.appbar.CollapsingToolbarLayout >

            <androidx.appcompat.widget.Toolbar />

        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>

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

    <com.google.android.material.floatingactionbutton.FloatingActionButton />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Design Support UI Widgets

I understand if all these layouts might appear new to you. But you won’t have to worry. I’ll do my best to explain to them, in the easiest way.

1. CoordinatorLayout

A powerful FrameLayout that specifies behavior for child views for various interactions. It also allows anchoring of floating views in your layout.

2. AppBarLayout

It is a special kind of vertical LinearLayout. It helps respond to its children’s scroll events (scroll gestures). Additionally, it’s responsible for implementing many features of Material Design’s AppBarLayout.

But, there’s one thing to note. Its usage relies on being a direct child within CoordinatorLayout. The layout skeleton above demonstrates this.

3. CollapsingToolbarLayout

It is a Toolbar wrapper which makes the ‘Flexible Space’ pattern possible. It collapses the image header while decreasing the expanded title to a Toolbar title.

4. FloatingActionButton

I’m sure you’re familiar with what a Floating Action Button is, aren’t you? Android gave it a thumbs up by giving us an official UI widget. It’s a part of the Design Support Library.

Project XML Layout

Alright, with that out of the way lets get to the actual XML. This is not a complex code. XML just tends to be a little verbose. But you’re welcome to try replicating the Flexible Space scroll animation in Java. Then I’m sure you’d truly appreciate how easy the Design Support library is.

activity_scrolling.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.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">

    <com.google.android.material.appbar.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">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            android:background="@drawable/legend_blogs"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:toolbarId="@+id/toolbar">

            <androidx.appcompat.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" />

        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>

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

    <com.google.android.material.floatingactionbutton.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" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

 

content_scrolling.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.core.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" />

</androidx.core.widget.NestedScrollView>

 

ScrollingActivity.java

package com.codingissue.legendblogsexample;

import android.os.Bundle;

import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import android.view.View;
import android.view.Menu;
import android.view.MenuItem;

public class ScrollingActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_scrolling);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_scrolling, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // 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.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

 

Conclusion

In Android, the Design Support Library makes it easy to create powerful animations, like this one. It allows us to create rich app experiences our users can enjoy. In the above code, to know whether the CollapsingToolbarLayout is collapsed or expanded. we add a listener addOnOffsetChangedListener on the AppBarLayout instance. Depending upon the if-else conditions we show or hide the toolbar info option.

 

Top