Android Small Talks: CoordinatorLayout, or one of the strengths of Android Design Support Library

Android Small Talks: CoordinatorLayout, or one of the strengths of Android Design Support Library

When Android Lollipop entered the market, there was a breakthrough. Google provided us with an extensive library of Android Design Support Library which facilitates creating applications that are compliant with the principles of Material Design. Creating a user interface in accordance with these guidelines introduces our software to the next level of design and user-application interaction.

Material Design focuses, among others, on creating beautiful animations, designing particular elements, but above all on consistency of all components. Considering these factors, it is not surprising that CoordinatorLayout was also introduced. This Layout is a new kind of container that is a FrameLayout further enhanced with the ability of creating dependencies between elements which are its children.

How to use CoordinatorLayout?

Using CoordinatorLayout is not at all complicated. Just put in it the views, which are to be included in the container, just like in any other case. Then add to them appropriate behavior.

Below you can see an example of creating a dependency of two components whose behavior is to be similar to the action of FloatingActionButton dependent from appearing SnackBar. One of the components is FAB from open source library, and the other is a self-created simple view, which was given similar behavior.

Add the library

In the first step we need to add Support Design Library to Gradle:

compile 'com.android.support:design:23.1.1'

Create a layout

Then, we need to create our layout with 2 components in XML. The final file looks like this:

<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"
	tools:context="com.example.dominika.coordinator.MainActivity">

	<com.getbase.floatingactionbutton.FloatingActionButton
    	android:id="@+id/lib_fab"
    	android:layout_width="wrap_content"
    	android:layout_height="wrap_content"
    	android:layout_gravity="bottom|end"
    	android:layout_margin="@dimen/fab_margin"
    	android:src="@android:drawable/ic_dialog_email"
    	app:layout_behavior="com.example.dominika.coordinator.FloatingButtonBehavior"
    	/>

	<com.example.dominika.coordinator.CustomView
    	android:id="@+id/customView"
    	android:layout_width="70dp"
    	android:layout_height="70dp"
    	android:layout_gravity="bottom|start"
    	android:layout_margin="@dimen/fab_margin"
    	/>
</android.support.design.widget.CoordinatorLayout>

What’s interesting to us is adding behavior of lib_fab view:

app:layout_behavior="com.example.dominika.coordinator.FloatingButtonBehavior"

To make this possible we need to take the next step, that is define behavior of a component used with an external library.

Adding view behavior

We do it by creating a new class. First of all, we should make sure that the class inherits from the Behavior class. In order to enable adding behavior by .xml file we need to create a builder with two arguments: AttributeSet and Context.

public class FloatingButtonBehavior extends CoordinatorLayout.Behavior<FloatingActionButton> {
	public FloatingButtonBehavior(Context context, AttributeSet attributeSet) {

	}
}

The next step is to override the method layoutDependsOn() and define which events we want to listen to. In this case, we are interested in appearing SnackBar.

@Override
	public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
    	  return dependency instanceof Snackbar.SnackbarLayout;
	}

Then we need to override the method onDependentViewChanged(), which specifies what is to happen with our view when the event we are listening to occurs. In our case, the view behavior which we add will be moving depending on SnackBar. In this method, we can read the current state of dependent view. Our goal is to move the view upwards, exactly by the height of the element on which it is dependent so we need to translate it along Y axis:

@Override
	public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
    	float translationY = Math.min(0, dependency.getTranslationY() - dependency.getHeight());
    	child.setTranslationY(translationY);
    	return true;	
  	}

At the same time an element that is important here is the return value. This value should always be true when the view changes its position on the screen.

So created behavior we can set in the view through an .xml file.

Adding behavior through an annotation

Besides adding dependencies in an .xml file, when we deal with our own view, we can add to it default behavior created by us. It can be done in a very clear way by adding annotations.

For this purpose there was created a similar class that defines behavior of a view. However, to enable creating annotations we must first add a constructor which doesn’t accept arguments:

public class CustomBehavior extends CoordinatorLayout.Behavior<CustomView> {
	public CustomBehavior() {}

When a class defining response of a view is ready, just add an annotation to your own view:

@CoordinatorLayout.DefaultBehavior(CustomBehavior.class)
public class CustomView extends View {

That’s it! In this way, any CustomView view we create has automatically defined behavior. You can see the result below:

CoordinatorLayout - short animation

To sum up, CoordinatorLayout is a Layout which enables easy creating of dependencies between its children. Thus it is another well-thought element of the library of Android Design Support Library. As shown, the whole process is simple and requires only following a few rules. Obviously, you will understand it best if you write something yourself, so I encourage you to test CoordinatorLayout on your own! 😉

Learn more

Android Small Talks: Backendless – an Alternative to Parse.com

Parse.com was one of the most popular MBaaS services (Mobile backend as a service). It facilitated creating a database in a cloud and made access to it available through an automatically generated API. Unfortunately, some time ago this project was announced to be closed, which forced us to find an alternative. From many websites of this sort, I have finally decided to choose Backendless.com.

Read more

Android Small Talks: Dependency Injection with Dagger 2

Dependency injection is a design pattern the main task of which is to free our code of dependencies. As we all surely realize, code with a minimal amount of dependencies is far easier to manage and change. It’s also easier to use and test such code.

Read more

5 Reasons Why You Should Build the UI in ConstraintLayout

ConstraintLayout is a popular solution that Android developers use every day. And not without a good reason. If you’re at the beginning of your journey as a software engineer, get familiar with the most important features this layout can offer. It will help you understand the way it works, and Android app development will become easier.

Read more

Project estimation

Let us know what product you want to build and how we can help you.

Why choose us?

Logo Mobile Trends Awards

Mobile Trends Awards 2021

Winning app in
EVERYDAY LIFE category

Nagroda Legalnych Bukmacherów

Legal Bookmakers Award 2019

Best Mobile App

Mobile Trends Awards logo

Mobile Trends Awards 2020

Nomination in SPORTS & RECREATION category

20

client reviews

Clutch logo