AppBarLayout scroll behavior with layout_scrollFlags

Since the introduction of AppBar in 2015, Android developers have spent lots of time styling and modifying it, making beautiful and unique apps. The ways of modifying Toolbar and flexible area beneath it are quite impressive. Yet, still the entry threshold is quite high for those who want to make their first steps in Material design world.

Partly, this is because of an incomplete documentation and the lack of diverse examples. I, myself struggled to make the layout I wanted and as easy as it sounds – to make it scroll the way I want to. This was the moment I decided to write this blog post, so it helps others ­čÖé

Maybe you want to scroll a Toolbar, so it hides completely and the only thing visible is the text? Or expand and collapse an image below the Toolbar? Or, doesn’t┬ámatter if the user is on the bottom of the layout, – you want to show him a Toolbar immediately on a scroll up action (there is a description of various scrolling techniques here). All of this is possible and easy to do with scroll flags!

Why do you need those flags in the first place? Well, when you want to have┬áexpandable Toolbar, Floating Action Button and a content to scroll over, the best option would be to put them into CoordinatorLayout and use its facilities in order to customize the behavior of each of those components. CoordinatorLayout bounds the behavior of a few views together. It makes them work as a whole – smooth and natural. You just need to put┬áToolbar┬áinto the AppBarLayout, which is a special version of a LinearLayout with a scrolling gestures, and put a content into NestedScrollView which then needs to have a behavior flag – app:layout_behavior in order to notify AppBarLayout when a scroll event occurs, so they could┬áwork together. This is very nicely described in here.

In case you’ve created a layout and haven’t specified app:layout_scrollFlags, Toolbar or whatever is inside AppBarLayout, will statically remain on top, always in an expanded state. If this is your intended behavior, then leave it as it is. If not, welcome to the rest of the blog post ­čśë

If you want to jump right into the source code, please check it out on the GitHub !

And so, I will discuss app:layout_scrollFlags attribute from AppBarLayout.LayoutParams. This attribute is responsible for a scrolling behavior of AppBarLayout and its children. You can apply it directly to AppBarLayout or on the inside views, in the xml layout of your AppCompatActivity. It has to be an instance of AppCompatActivity if you want to use AppBar features. Also, the design library must be included in Gradle dependencies, like so: implementation 'com.android.support:design:26.1.0'

Basically, app:layout_scrollFlags attribute must have one of the 5 values (or a few of them combined). In my examples I use a Toolbar with action items, so my explanations are based on it.

scroll Toolbar scrolls with the rest of the content, just like a regular view on the layout.

scroll flag behavior

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBarLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_scrollFlags="scroll"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

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

enterAlways –┬áToolbar scrolls with the rest of the content, just like a regular view on the layout. The difference to scroll flag, is that even on the slightest scroll up, the Toolbar will immediately show up, no matter if the content is on top or not. This is a so-called “quick return”┬ádesign pattern. I would recommend this flag in case┬áthere is some important┬áand highly used item on the Toolbar, so the user has an immediate access to it.

enterAlways flag behavior

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBarLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

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

enterAlwaysCollapsed – an additional flag┬áto use with┬áenterAlways, in cases where you have a CollapsingToolbarLayout. If you┬áput enterAlways only, you’ll end up┬áwith an expanding layout on every scroll up action and that’s probably not what you want ­čÖé With this flag, the layout is expanding only when the content has been scrolled all the way up. As for the collapsed┬áToolbar, it appears on every scroll up action.

Here I have to mention an app:layout_collapseMode attribute. It’s really important to add app:layout_collapseMode="pin" to the Toolbar, otherwise the action items won’t show when the layout is scrolled. I recommend putting app:layout_collapseMode="parallax" for an┬áImageView┬áin order to have a nice scrolling effect.

enterAlwaysCollapsed flag behavior

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBarLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsingToolbarLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed">

            <ImageView
                android:id="@+id/imageViewCollapsing"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:src="@drawable/winterscenery"
                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>

exitUntilCollapsed – the name of this flag says for itself. On scroll down, CollapsingToolbarLayout┬áhides only till collapsed state, which is based on the min height. So, in our case it’s Toolbar’s height.┬áThis way, it will always be visible and when scrolled all the way up – will expand the flexible area beneath it (in our case – ImageView).

This flag is probably the most common and suitable for a Details view, with ImageView and CardViews below. Again, you need to add app:layout_collapseMode="pin" on the Toolbar, so the action items are shown on scroll.

exitUntilCollapsed flag behavior

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBarLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsingToolbarLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <ImageView
                android:id="@+id/imageViewCollapsing"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:src="@drawable/winterscenery"
                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>

snap – this flag provides a “sticky” scroll behavior. Based on how far from the top the AppBarLayout is, it will either fast scroll to hide or show completely. Imagine there’s a line in the middle of a Toolbar, exactly on 50% of its height. If you scroll up, so 51% of Toolbar is invisible, it will “jump up” to hide, if 49% is invisible and you scroll down, it will fully be shown.┬á The snap flag┬ácan be used with other flags as a further customization.

snap flag behavior

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBarLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_scrollFlags="scroll|snap"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

        <android.support.design.widget.TabLayout
            android:id="@+id/tabLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <android.support.design.widget.TabItem
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="One" />

            <android.support.design.widget.TabItem
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Two" />

            <android.support.design.widget.TabItem
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Three" />
        </android.support.design.widget.TabLayout>
    </android.support.design.widget.AppBarLayout>

Important thing to mention, is that scroll flag should always be specified, as a first value, i. e. “scroll|enterAlways”. When you check the source code of AppBarLayout, you’ll see┬áthere is a check for a scroll flag, if it’s not there – everything else┬áis ignored.

To simplify the decision of which flag to choose for your own need, I’ve made this comparison table:

Does it make sense now? ­čÖé I hope you understand more about scroll flags after reading this post. Please write a comment if something’s unclear. Thanks!

Source code:

On GitHub ­čÖé

Read more:

Scrolling Behavior for Appbars in Android

Handling Scrolls with CoordinatorLayout

Material Scrolling techniques

Material Design Components

AppBarLayout documentation

AppBarLayout Oreo source code

Like and share:

Published by

Tonia Tkachuk

I'm an Android Developer, writing code for living and for fun. Love beautiful apps with a clean code inside. Enjoy travelling and reading.

131 thoughts on “AppBarLayout scroll behavior with layout_scrollFlags”

  1. thanks Tonia. very well written article!
    but I think, what you mean by scroll up is basically the user dragging his finger towards the bottom, so I guess that should be scroll down, right?

  2. Pingback: viagra for sale
  3. Pingback: buy viagra online
  4. Pingback: buy cialis brand
  5. Pingback: buy cialis 36 hour
  6. Pingback: cdxgkuop
  7. Pingback: comprar viagra
  8. Pingback: amoxil 500mg
  9. Pingback: pregnant on clomid
  10. Pingback: dose of synthroid
  11. Pingback: neurontin 900 mg
  12. Pingback: covid 19 plaquenil
  13. Pingback: buy cialis toronto
  14. Pingback: Zakhar Berkut hd
  15. Pingback: buy insurance
  16. Pingback: isotretinoin buy
  17. Pingback: 20 mg cost
  18. Pingback: 20 mg cost
  19. Pingback: Google
  20. Meme k├╝├ž├╝ltme ki┼činin kendi iradesiyle sark─▒kl─▒k yapan derilerin ve a─čr─▒l─▒k yapan k─▒s─▒mlar─▒n ├ž─▒kar─▒larak daha estetik bir ┼čekle kavu┼čturulmas─▒ olarak a├ž─▒klan─▒r.

  21. Pingback: meritroyalbet
  22. Pingback: meritroyalbet
  23. Pingback: madridbet
  24. Pingback: meritroyalbet
  25. Pingback: makrobet
  26. Pingback: amoxicillin 825 mg
  27. Pingback: slot siteleri
  28. Pingback: makrobet
  29. Pingback: discount neurontin
  30. Pingback: arzbet
  31. Pingback: quineprox 40 mg
  32. Pingback: arzbet
  33. Pingback: order prednisone
  34. Pingback: dapoxetine drug
  35. Pingback: combivent inhaler
  36. Pingback: neurontin pills
  37. Pingback: avana 50
  38. Pingback: provigil online
  39. Pingback: kronosslot

Leave a Reply

Your email address will not be published.