Using Coordinator Layout in Android

If you have used FrameLayout in your application, then you know that it is a very difficult task to manage views one over the other in FrameLayout. Also, it is advised not to use more than one element in our FrameLayout. The reason behind this is, you have to explicitly handle the motions or you may say the animations of all the views that are present on a particular page of your mobile application.

So, in order to handle the views in a better way, Android introduced a new layout called the Coordinator Layout. By using Coordinator layout you can easily handle and animate the transitions of views present in a Coordinator Layout. To have a clear understanding of the usage of Coordinator Layout, please open your WhatsApp application. Now, open any chat and click on the name of the chat or go to the menu and then click “View Contact”. Here, you will find the profile picture of the user. Now try to scroll down the page. Hey, where is the profile image? Now scroll up. Yeah, you got the profile image? Try to repeat the same scrolling up and down and see the animation. This is done with the help of Coordinator Layout. Another example of Coordinator Layout can be seen below:

Here, we can see that one view is going over the other and the transaction or animation between these views is very smooth. That’s the power of Coordinator Layout.

So, in this blog, we will learn about Coordinator Layout and we will use this layout in our Android application. So, let’s get started.

What is Coordinator Layout?

According to the official documentation of Android:

CoordinatorLayout is a super-powered FrameLayout.

At the Google I/O 2015, Google introduced Coordinator Layout to remove the difficulties of having more than one layouts in FrameLayout. Now, by using CoordinatorLayout you can see how views can interact with each other in a particular layout. CoordinatorLayout controls the animation and transactions of various child elements with one another. We have seen various examples of CoordinatorLayout in the introduction section of the blog. After looking at the examples, one question that might come in your mind is that how the CoordinatorLayout knows what to do with the child present in CoordinatorLayout? Let’s try to find the answer.

Behaviors

Whenever a view is interacting with the other then it is done with the help of Behaviors. We create a particular behavior for a particular view and these behaviors are responsible for animations between the views. Some of the common Material Design behaviors are sliding drawers, swipe-dismissal, floating action button, a sticky button that stick on some other view. So, broadly these behaviors can be classified into two types:

  1. Layout-Based: Layout-Based behaviors are used to shift one view at some other place when you perform a certain task. For example, create a project in Android Studio with Basic Activity template. Now, run the application on your mobile. You will find a Floating Action Button on the screen. Just press the button and you will find a snackbar coming from the bottom of the screen. At the same time, you will notice that the Floating Action Button has moved upwards. After a few seconds the button will again come back to its original position.
  2. Scroll-Based: Scroll-Based behaviors are the most common use of Coordinator Layout. Remember the example of WhatsApp, that we discussed in the introduction section. When you scroll the profile or contact page in WhatsApp, then you will find that the profile image will be changed to ActionBar. So, these type of behaviors is called Scroll-Based behaviors.

Learn System Design for your next Interview from here.

Coordinator Layout example

In this section of the blog, we will look upon some of the examples of Coordinator Layout. Firstly we will try to implement the Floating Action Bar in our application.

Implementing Layout-Based Behavior

Let’s create an Android Project in Android Studio using the Blank Activity template. If you are not using a Blank Activity then you can create an Empty Activity and use the code used in the blog. If you have used the Blank Activity template then you can run your app to see the use of Coordinator Layout otherwise you can follow the below steps after creating an Empty Activity.

After creating a project, our first step is to add the design dependency in our app level build.gradle file (if not added).

implementation 'com.android.support:design:x.x.x'

After adding the dependency, you have to add one layout file i.e. at this step you will be having two layout files. First layout file will be used to display the contents of MainActivity and the second layout file will be used to define CoordinatorLayout and handle the animations and transactions of the views in the Activity. So, following is the code for the content_main.xml file:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:showIn="@layout/activity_main"
        tools:context=".MainActivity">

    <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello MindOrks!"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

After creating the content file, you have to include this file in your CoordinatorLayout file. So, add the below code in your main_activity.xml file:

<?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"
        tools:context=".MainActivity">

    <com.google.android.material.appbar.AppBarLayout
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:theme="@style/AppTheme.AppBarOverlay">

        <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:popupTheme="@style/AppTheme.PopupOverlay"/>

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

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

    <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="@dimen/fab_margin"
            app:srcCompat="@android:drawable/ic_dialog_email"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

After add the code for the UI part, now let’s move on to the code for the MainActivity.kt file. Following is the code for the same:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(toolbar)

        fab.setOnClickListener { view ->
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                .setAction("Action", null).show()
            //here you can put your own action
        }
    }

    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_main, 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)
        }
    }
}

Finally, run your application and press the Floating Action Button to view the Snackbar from the bottom of the screen. Also, at the same time, the FAB will be moved upwards and again come back to its original position after some seconds.

Implementing Scroll-Based Behavior

Scroll-Based behaviors are mostly used behaviors. Here we scroll one view to overlap on to the other view. One common example of Scroll-Based behavior is Collapsing Toolbar Activity i.e. something like WhatsApp Collapsing Toolbar. So, let’s implement the same.

Either create a new Project or create a new Activity (if you are creating new Activity, then you have to call that activity from the MainActivity by using some Buttons or you can use the previously made FAB button to call the newly created Activity). In my case, the name of the Activity is CollapsingToolbarActivity.

Here, in this Activity, we will make use of the CollapsingToolbarLayout to achieve our goal. Let’s write the code for the activity_collapsing_toolbar.xml file.

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

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

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsingToolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleMarginEnd="56dp"
            app:expandedTitleMarginStart="40dp"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:title="Hello MindOrks!">

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

            <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/ThemeOverlay.AppCompat.Light" />
        </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"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:lineSpacingExtra="8dp"
            android:padding="16dp"
            android:text="@string/long_text"
            android:textSize="24sp" />
    </android.support.v4.widget.NestedScrollView>

    <android.support.design.widget.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:src="@drawable/mascot_icon"
        app:layout_anchor="@id/appBar"
        app:layout_anchorGravity="bottom|end" />
</android.support.design.widget.CoordinatorLayout>

Here, in the ImageView you can find one attribute called layout_collapseMode which is used to define the collapse mode of the image when the scrolling task is performed. We have used Parallax mode for the ImageView and Pin mode for Toolbar. Also, you can use layout_collapseParallaxMultiplier to define what part (percentage) of Image you want to collapse on scrolling.

Nothing more to be done. Hey! Don’t we need to write codes in the .kt file? No, we are done. Here is the code for the CollapsingToolbarActivity.kt file:

class CollapsingToolbarActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_collapsing_toolbar)
    }
}

Run the application and try to scroll up and down. Also, increase the number of lines of texts in the TextView to have a more clear understanding.

Conclusion

In this blog, we learned how to use Coordinator Layout in our application. Coordinator Layout is used to manage the transactions and animation of various views present in an Activity. Before Coordinator Layout, Frame Layout was used, but using more than one views in Frame Layout results in overlapping of views over one another. At the end of the blog, we did some examples to have a clear understanding. Hope you enjoyed the blog.

Keep Learning :)

Team MindOrks!