At this year’s I/O developers conference, Google introduced a new Android Design Support Library to help developers use material design in their apps. It contains many important material design building blocks and it works for API level 7 and higher. If you somehow missed it check out the google android blog post right here: http://android-developers.blogspot.com/2015/05/android-design-support-library.html.

Meet Android CoordinatorLayout

Among all the goodies the one that looks really interesting is the new “super-powered” FrameLayout called CoordinatorLayout. As you may have guessed from its name, the super power of this layout is the ability to coordinate dependencies between child views.

All you need to do is to wrap views inside CoordinatorLayout. Let’s dive into the code. The demo is very simple; it contains Floating Action Button which triggers a Snackbar.

First, add Support Design Library in gradle:
compile 'com.android.support:design:22.2.0'

Now lets create a simple layout for our activity

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    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="end|bottom"
        android:layout_margin="16dp"
        android:src="@drawable/ic_done" />

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

And the main activity class:

public class MainActivity extends AppCompatActivity {

  @Override  
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        Snackbar.make(view, "Hello Snackbar", Snackbar.LENGTH_LONG).show();
      }
    });
  }
}

Demo time:

android_snackbar1

That’s pretty cool, huh?

But what happens if you want to use other FAB implementation? FAB implementation from Support Library doesn’t have menu options so let’s try an alternative open source FAB library created by one of Base’s developers.

compile 'com.getbase:floatingactionbutton:1.9.1'

<?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">

    <com.getbase.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="16dp"
        app:fab_icon="@drawable/ic_done" />

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

The CoordinatorLayout doesn’t work out of the box in that case. That’s because our view doesn’t have a default CoordinatorLayout.Behavior implementation. The solution? We’ll either have to wait until someone adds it…

…or we can do this ourselves by writing custom Behavior implementation for that view in our project.

Views learn how to behave

That’s the real power of this framework, you don’t have to have access to the view’s class to make your own behavior for that view. You can also change a default behavior for any view.

First we need to extend Behavior class:

public class FloatingActionButtonBehavior extends CoordinatorLayout.Behavior<FloatingActionButton>

To make that class inflatable from XML we need to add constructor with Context and AttributeSet parameters.

public FloatingActionButtonBehavior(Context context, AttributeSet attrs) {}

Next step is to override method layoutDependsOn() and return true if we want to listen for changes. In our case we want to listen only for Snackbar objects changes.

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

Now let’s go to the actual behavior implementation. Method onDependentViewChanged is called each time depended view changes inside CoordinatorLayout. In this method we can read the current Snackbar view state. We want to move FAB up when Snackbar shows up. To do this we need to translate the Y of the FAB view to the height of the Snackbar view. Snackbar animation starts with Y translation set to Snackbar height and to get the right translation value we need to subtract Snackbar height from its translate Y value. According to documentation we should return true when the object changes its position on the screen.

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

Last part is to tell the CoordinatorLayout to use FloatingActionButtonBehavior for that view. We can do this in 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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.getbase.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="16dp"
        app:layout_behavior="com.getbase.coordinatorlayoutdemo.FloatingActionButtonBehavior"
        app:fab_icon="@drawable/ic_done" />

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

And that’s it. The proof:

android_snackbar3

If you want to define a default behavior to your view just add DefaultBehavior annotation with path to your Behavior class.

The code from this blog post is also available on github: https://github.com/ggajews/coordinatorlayoutwithfabdemo

Happy coding!

Posted by

Grzesiek Gajewski

Share this article

  • Great tutorial, especially the part about the custom behavior definition!

    • Grzegorz Gajewski

      Thank you! Yes, custom behavior gives developers great flexibility.

  • Sam

    Can CoordinatorLayout be a child of another view group like RelativeLayout?

    • Grzegorz Gajewski

      Yes, it works just like FrameLayout.

  • Aily

    Hello the tutorial is really great but i cant do anything of it because i don’t have the Design Support Library in my repository and i cant use the sdk manager to download it because of some work restrictions, can you help to find it in another place i need to do manually download.

    • Grzegorz Gajewski

      You can try to download it somewhere else and copy android-support-design.jar from Androidsdkextrasandroidsupportdesignlibs

  • Peter

    Can CoordinatorLayout manage any kind of child view instead of just a view pager?

  • tatacarrera

    Android Studio reports that: Cannot resolve symbol: @drawable/ic_done Is there anything else I should import?

  • Peter

    Can Coordinator Layout work with any view containers or does it need a ViewPager?

  • Adam Purser

    Thanks alot man, Great tutorial :)

  • Dima

    I know that the default FAB moves out of the way of Snackbar when its shown. What if I want to make my own custom method, to hide FAB when scrolling.. so the

    public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
    return dependency instanceof AppBarLayout;
    }
    As you can see it returns AppBarLayout rather than SnackBar.. can we have both and implement both ?

    • Grzegorz Gajewski

      Sure we can. Unfortunately if you specify custom Behaviour class you need to provide implementation for all cases.
      So your layoutDependsOn() method should return:
      return dependency instanceof AppBarLayout || dependency instanceof SnackbarLayout;

      and then handle both implementations inside onDependentViewChanged()

  • Nava Ighani

    When I add new simple component (for example Button) FAB does not work correctly as well as later. What is the solution?

    • Grzegorz Gajewski

      It’s hard to tell what’s wrong from description. Can you post a sample project to show the issue?

  • Armin Ghoreishi

    Hi.
    How can we create scrolling behavior depends on AppBarLayout for FrameLayout or another views which is not designed to work with coordinator layout.
    tanx

    • Grzegorz Gajewski

      That is probably good topic for another blog post so stay tuned!

  • Thomas Bruyelle

    Very great stuff here thanks !

  • Awesome tutorial. Thank you Grzesiek!

  • Taras

    On first install application FAB is not in his place, it is much more above.

    • Grzegorz Gajewski

      If this is related to the demo application, please create issue on github.

  • Mwesigye Johnbosco

    cool stuff. thanks for the article

  • Guster

    Awesome! Never I know how to make custom behavior, thanks

  • Grzegorz Gajewski Excellent blog!
    Is the solution to this -> http://stackoverflow.com/questions/32597386/coordinatorlayout-behavior-not-respond-to-child-view

    to implement NestedScrollingChild on a class that extends the DrawerLayout?

    • Grzegorz Gajewski

      There are two problems there, the first one is mention by you: DrawerLayout doesn’t implement NestedScrollingChild. The second one is that unfortunately CoordinatorLayout only coordinates it’s direct children and not the nested views. In your case DrawerLayout should be a child of CoordinatorLayout.

      • Oh no! :/ i was really hoping that there was some way to implement the nestedscrollingchild and have the coordinator layout listen to it :/

        • Grzegorz Gajewski

          You got me wrong, there is a way:
          1. Implement NestedScrollingChild on a class that extends the DrawerLayout
          2. Insert your new DrawerNestedScrollingChildLayout as a child of CoordinatorLayout

  • Cholly Cholly

    Thanks guys!

  • Android Developer

    I think I’ve found an issue which is related to RecyclerView and the CoordinatorLayout:
    https://code.google.com/p/android/issues/detail?id=186513

    If anyone has found a workaround for this, please let me know.

  • mart6049

    Great tutorial. Do you know if this can be implemented with FloatingActionMenu?

  • Carlo Conserva

    Hello,
    thank you very much, this tutorial has been very useful, but I am experiencing a problem.
    I have implemented a custom behaviour like yours for my custom FAB view, and it works perfectly as long as you don’t swipe away the snackbar message.. if you do, the custom FAB remains translated and does not return to its original position. I guess it’s needed to implement some other Behavior method to handle this case too.. do you have any suggestions?

    • Carlo Conserva

      I’ve found out myself, it was quite easy actually.. just add this method to the custom Behavior class and the problem is solved:

      @Override
      public void onDependentViewRemoved(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
      super.onDependentViewRemoved(parent, child, dependency);
      child.setTranslationY(0);
      }

  • L

    Hey. Nice tutorial but I would like to ask what should be added to handle snackbar dismiss by swipe. After it custom view does not back to previous position like FAB from support lib.

    • Grzegorz Gajewski

      Please take a look at the comment from @carloconserva:disqus. Does it answer your question?

      • L

        I don’t know why I missed this comment. Now it’s working. Thanks

  • Flavio Filho

    Hi, thank you by the nice tutorial!
    I would like to use coordinatorLayout to create a Persistent Bottom Sheet as described in https://www.google.com/design/spec/components/bottom-sheets.html

    Do you think it´s possible?
    Any ideas would be appreciated.

  • Mehul Shah

    Amazing Tutorial

    I was afraid to use all this components, but now I am becoming confident
    Thanks alot

  • Very nice

  • Łukasz Wiśniewski

    Nice read, I’ve modified the sample a bit to take into account larger screens, where this animation should not happen.


    @Override public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionsMenu child, View dependency) {
    // only animate if views would overlap on the screen
    if ((dependency.getLeft() < child.getLeft() && child.getLeft() < dependency.getRight()) ||
    (dependency.getLeft() < child.getRight() && child.getRight() < dependency.getRight())) {
    float translationY = Math.min(0, dependency.getTranslationY() - dependency.getHeight());
    child.setTranslationY(translationY);
    }
    return true;
    }

    • Didn’t work for me using SnackbarLayout and FloatingActionsMenu. ¯_(⊙_ʖ⊙)_/¯

  • Rev. Kyle Vanhove

    Great tutorial, works exactly as I needed it to, but for my buttons. I actually set up onClickListeners for a couple rows in my UI, and I need to call the method when they’re clicked. Is that possible?

    • Grzegorz Gajewski

      I’m not sure if I get your question correctly. Can you post a sample code/design somewhere?

      • Rev. Kyle Vanhove

        I tried applying this to an OnClickListener I set up on a LinearLayout, but it didn’t work. I switched to buttons and made sure to name my layout’s id and it worked. Thanks for your help!

  • Puneet Akhouri

    Great tutorial, works like a charm.

  • Mahdi Mortazavi

    very nice <3

  • Ali

    Everywhere I read about Co-ordinator layout I only see its usefulness with a Snackbar and FAB. The Snackbar displaces FAB. Thats good but seriously, is that all the Coordinator layout can do? I dont have a Snackbar in my app so I dont see a point in replacing all my Layouts to Coordinator. Too much work for what?

    • Grzegorz Gajewski

      Snackbar and FAB are just good for this example. Changing your layouts to Coordinator is pointless unless you want your views to cooperate. The other great usage example is hiding AppBarLayout on scrolling in RecyclerView. CollapsingToolbarLayout also looks interesting.

  • Igor Oliveira

    Hey guys, thanks for this tutorial! The code to calculate the translationY saved me!

    • Approve.

      *–Zbyszek Motak*
      Team Growth

      zbyszek@getbase.com
      +48 501 396 742
      *Base Lab – Engineering Optimized for Impact *

  • Alex

    Does Coordinatorlayout can have many childs? Slide not working when a add another child to CoordinatorLayout

    • Grzegorz Gajewski

      Sure. As you can read in docs ‘CoordinatorLayout is a super-powered FrameLayout’. Maybe the view you are adding is consuming the scroll.

  • Lucas Marciano

    Hi, I use this lib: compile ‘com.github.clans:fab:1.4.0’
    but I can not do the fab down, just up.
    Please help me