A couple of tricks with Android’s CollapsingToolbarLayout

Tagged: , , , ,

Recently I had some fun with CollapsingToolbarLayout, and I learned a few tricks that I would love to share. When using this piece of magic it is very easy to implement material behaviour, your App looks amazing with very little effort. However you might find that you want something slightly different sometimes, and find yourself stuck googling for a solution, or digging into the code.

This happened to me because I wanted to be able to lock the CollapsingToolbarLayout, meaning that I wanted to prevent the user from expanding and collapsing the toolbar by dragging his finger. However I still needed the collapsing behaviour to work programmatically. Took me longer than expected to figure this out, however the solution turned out to be pretty easy, this is the result

You can download or clone the demo project from GitHub


The trick is a good understanding of CoordinatorLayout and Behavior, these are the two components responsible for the magic happening when using CollapsingToolbarLayout, in fact you always need a CoordinatorLayout when doing this. There is nothing really interesting going on in the xml layout, all the magic happens through code. I created a custom Behavior for the AppBarLayout, which does two things, it blocks drag events on the toolbar and it prevents the AppBarLayout from reacting to nested scroll events. Nested scroll events are fired by the NestedScrollView that holds my content, in this case two checkboxes and one button, when scroll events are triggered by the NestedScrollView they get dispatched to the top level CoordinatorLayout which then orchestrates the whole material magic by asking every view for their behavior and acting accordingly. Every view inside a CoordinatorLayout can provide a behavior and this encodes how that view will react to scroll events.

The custom Behavior that I used for AppBarLayout looks like this

Two things are happening here, drag interactions from the toolbar can be blocked and nested scroll events can be refused.

Prevent the user from dragging the toolbar to expand or collapse the AppBarLayout

To block user interactions when the toolbar is dragged I set a drag callback which returns the enabled state of the interaction, this state can be set programmatically so it is possible to enable and disable user interactions via code. The system will use this call to determine whether or not to accept drag events.

Prevent the user from scrolling the content to expand or collapse the AppBarLayout

This is achieved by accepting or refusing nested scroll events, the onStartNestedScroll() method does exactly that, it also uses a flag that can be set programmatically. When CoordinatorLayout will ask AppBarLayout how it wants to deal with nested scroll events we will simply say that it does or it does not, depending on the flag, and CoordinatorLayout will stop further dispatching of callbacks related to nested scroll events.

Setting the new Behavior for AppBarLayout

With the Behavior in place I just had to actually use it


I packaged these two functionalities into a controller class that is ready to be used in other projects, so feel free.
Also, I created a demo project on GitHub to demonstrate this in action.

That’s pretty much it, I hope this was useful and please let me know in the comments!

Unique opportunity! Help a fellow grow his blog!

Hi there! If you’ve read this far maybe you think this was useful, or fun, or I don’t know what but for some reason You Got Here! Great! Please consider sharing this post with your network, I am trying to get The Code Butchery to grow so I can provide more content like this, will you help me in my journey? Thank you!

Share this

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.