Search

Customizing CoordinatorLayout’s Behavior

Chris Stewart

4 min read

Feb 2, 2016

Customizing CoordinatorLayout’s Behavior

When the Android design support library dropped a few months ago, developers were given all kinds of goodies. Most of these goodies are self-explanatory: The floating action button, you’ve seen that. Snackbars and Tabs? Everyone knows what those are.

But there is also something mysterious lurking in the design support library. Something that has its tentacles throughout. This mysterious thing is known as the CoordinatorLayout.

CoordinatorLayout

You don’t hear much about CoordinatorLayout, probably because when you use it, you generally don’t need to know many of the details. Things just work and they just work well. However, CoordinatorLayout is more powerful than it first seems.

Take a snackbar and a floating action button as an example. Using a CoordinatorLayout, you can ensure that your floating action button will move out of the way when the snack bar pops in.

Just throw a CoordinatorLayout in your layout file:

<android.support.design.widget.CoordinatorLayout
  android:id="@+id/container"
  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.FloatingActionButton
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|right|end"
    android:layout_margin="8dp"
    android:src="@drawable/abc_ic_search_api_mtrl_alpha"/>

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

Then show your snack bar:

Snackbar.make(findViewById(R.id.container), "Hey there!", Snackbar.LENGTH_LONG).show();

Magically, your floating action button will move when the snack bar shows up. That’s it!

Moving Floating Action Button

Out of the box, CoordinatorLayout can also increase the size of your toolbar based on scroll position or hide your toolbar when the user is scrolling down a list. You can customize it with your own behavior, too.

So how does CoordinatorLayout know what to do with the floating action button? How does it know that it should move up the screen when the snack bar comes in?

CoordinatorLayout makes this happen by making use of a CoordinatorLayout.Behavior implemented and declared by FloatingActionButton.

CoordinatorLayout.Behavior

Views within a coordinator layout can specify a Behavior that defines how that view interacts with other views.

@CoordinatorLayout.DefaultBehavior(FloatingActionButton.Behavior.class)
public class FloatingActionButton extends ImageView {
  ...
}

If you look at the source for FloatingActionButton, you will see its Behavior defined with an annotation on the class declaration.

FloatingActionButton uses FloatingActionButton.Behavior as its default behavior unless you set it to something else. The default knows how to get out of the way of the snackbar when it shows up.

Custom Behavior

So, how do you customize this behavior? You define your own Behavior subclass.

Let’s create a Behavior that shrinks the FloatingActionButton instead of moving it up the screen when the snackbar shows up.

Shrink the Floating Action Button

First, in your layout file, use the app:layout_behavior attribute to point to your Behavior subclass:

...

<android.support.design.widget.FloatingActionButton
  android:id="@+id/fab"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_gravity="bottom|right|end"
  android:layout_margin="8dp"
  android:src="@drawable/abc_ic_search_api_mtrl_alpha"
  app:layout_behavior="com.bignerdranch.android.custombehavior.ShrinkBehavior"/>

...

Then, create your class:

public class ShrinkBehavior extends CoordinatorLayout.Behavior<FloatingActionButton> {

  public ShrinkBehavior(Context context, AttributeSet attrs) {
      super(context, attrs);
  }

}

When you define your own behavior, there are many methods that you can override. For this example, there are two that are necessary:

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

The layoutDependsOn method is CoordinatorLayout’s way to see which views your floating action button are dependent on. In this case, if the view is a snackbar, set up a dependency by returning true.

The Android documentation indicates that by setting up this dependency, you will receive calls to onDependentViewChanged when a dependent view changes its size or position. This is true, but CoordinatorLayout’s source provides more detail. onDependentViewChanged is called whenever ViewTreeObserver.OnPreDrawListener.onPreDraw is called or when a scroll or fling action occurs.

@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
  float translationY = getFabTranslationYForSnackbar(parent, child);
  float percentComplete = -translationY / dependency.getHeight();
  float scaleFactor = 1 - percentComplete;

  child.setScaleX(scaleFactor);
  child.setScaleY(scaleFactor);
  return false;
}

As the snackbar moves up the screen, this method is repeatedly called. You can do a little math to determine how far up the screen the snackbar is and change your floating action button’s size as a result. You can see the full implementation of this ShrinkBehavior class on GitHub. You can find the source for this sample and another custom Behavior that rotates the floating action button there as well.

Mark Dalrymple

Reviewer Big Nerd Ranch

MarkD is a long-time Unix and Mac developer, having worked at AOL, Google, and several start-ups over the years.  He’s the author of Advanced Mac OS X Programming: The Big Nerd Ranch Guide, over 100 blog posts for Big Nerd Ranch, and an occasional speaker at conferences. Believing in the power of community, he’s a co-founder of CocoaHeads, an international Mac and iPhone meetup, and runs the Pittsburgh PA chapter. In his spare time, he plays orchestral and swing band music.

Speak with a Nerd

Schedule a call today! Our team of Nerds are ready to help

Let's Talk

Related Posts

We are ready to discuss your needs.

Not applicable? Click here to schedule a call.

Stay in Touch WITH Big Nerd Ranch News