Where should 'app:layout_behavior' be set?

89,515

Solution 1

Check this link: https://developer.android.com/reference/android/support/design/widget/AppBarLayout.html

AppBarLayout also requires a separate scrolling sibling in order to know when to scroll. The binding is done through the AppBarLayout.ScrollingViewBehavior class, meaning that you should set your scrolling view's behavior to be an instance of AppBarLayout.ScrollingViewBehavior. A string resource containing the full class name is available.

They mentioned about that, it should be the View which will be shown under the AppBarLayout 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"
         android:layout_width="match_parent"
         android:layout_height="match_parent">

     <android.support.v4.widget.NestedScrollView
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             app:layout_behavior="@string/appbar_scrolling_view_behavior">

         <!-- Your scrolling content -->

     </android.support.v4.widget.NestedScrollView>

     <android.support.design.widget.AppBarLayout
             android:layout_height="wrap_content"
             android:layout_width="match_parent">

         <android.support.v7.widget.Toolbar
                 ...
                 app:layout_scrollFlags="scroll|enterAlways"/>

         <android.support.design.widget.TabLayout
                 ...
                 app:layout_scrollFlags="scroll|enterAlways"/>

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

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

My question is: in what exact ViewGroup (or maybe View) should we put that app:layout_behavior?

And in this link: http://guides.codepath.com/android/Handling-Scrolls-with-CoordinatorLayout

Next, we need to define an association between the AppBarLayout and the View that will be scrolled. Add an app:layout_behavior to a RecyclerView or any other View capable of nested scrolling such as NestedScrollView. The support library contains a special string resource @string/appbar_scrolling_view_behavior that maps to AppBarLayout.ScrollingViewBehavior, which is used to notify the AppBarLayout when scroll events occur on this particular view. The behavior must be established on the view that triggers the event.

Solution 2

Make sure you added the appbar_scrolling_view_behavior field in your String.xml

<!-- The class name to the ScrollingChildBehavior required for AppBarLayout -->
<string name="appbar_scrolling_view_behavior" translatable="false">android.support.design.widget.AppBarLayout$ScrollingViewBehavior</string>

And as everyone knows we just can use this like below

<android.support.v7.widget.RecyclerView
        android:id="@+id/rvSomeList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

Its just for info not OP answer.

Solution 3

app:layout_behavior should be set to those views which are direct child of Coordinator layout

Solution 4

AppBarLayout also requires a separate scrolling sibling in order to know when to scroll.

This description from Android is woefully incomplete and caused me hours of wasted time.

Scrolling sibling is a misnomer and need not be a scrolling view of any type.

For example, below my AppBarLayout, I'm using a ViewPager2 that will render a Fragment that will render a Scrollview, so I needed to set app:layout_behavior="@string/appbar_scrolling_view_behavior" directly on the ViewPager2 in the main layout, NOT the deeply nested Scrollview in the fragment layout.

I also have no use for scrolling the AppBarLayout or any of its children on or off the screen, so I falsely assumed I could get away with not setting the app:layout_behavior anywhere.

Wrong.

This reveals a more insidious issue: AppBarLayout requires the scrolling sibling, yes. But not just to "know when to scroll", but to actually adjust the size of the sibling to fit properly on screen alongside it! Otherwise, the sibling maintains its configured size and will be nudged downward offscreen by the height of the AppBarLayout! You can even see this in Android Studio's layout editor.

Long story short: If you're going to use an AppBarLayout, you need to mark one of your views with app:layout_behavior="@string/appbar_scrolling_view_behavior", whether it's a scroll view or not.

Solution 5

I had to add the following to the gradle file otherwise it gave me a compile error.

implementation 'com.google.android.material:material:1.0.0'

Hope this would help some others too!

Share:
89,515
Evin1_
Author by

Evin1_

Life goal: Breaking a piñata in a small town party to get all the candy.

Updated on March 07, 2021

Comments

  • Evin1_
    Evin1_ about 3 years

    Should it be set at the AppBarLayout sibling's parent or at the first Scrollable View inside its sibling?


    With Material Design for Android, there are Views that let us work with the behavior of the layout depending on its surroundings, one of them is the CoordinatorLayout, as this CodePath guide mentions:

    CoordinatorLayout extends the ability to accomplish many of the Google's Material Design scrolling effects. Currently, there are several ways provided in this framework that allow it to work without needing to write your own custom animation code.

    The one I'm interested in now is:

    • Expanding or contracting the Toolbar or header space to make room for the main content.

    So, we would use the AppBarLayout with a Toolbar with app:layout_scrollFlags set and another ViewGroup sibling to the AppBarLayout with app:layout_behavior.

    My question is: in what exact ViewGroup (or maybe View) should we put that app:layout_behavior?


    So far, I've tried with (And they have all worked, and they are all siblings to the AppBarLayout):

    • Scrolling View

    • First ViewGroup inside a Scrollable View

    • ScrollView inside a ViewGroup

    And this one didn't work:

    • ViewGroup with no Scrollable View children.

    There are multiple examples online, but none of them really state where should you put it, like:

    http://www.ingloriousmind.com/blog/quick-look-on-the-coordinatorlayout/ https://guides.codepath.com/android/Handling-Scrolls-with-CoordinatorLayout https://developer.android.com/training/basics/firstapp/building-ui.html https://www.bignerdranch.com/blog/becoming-material-with-android-design-support-library/

  • eRaisedToX
    eRaisedToX about 7 years
    What is coordinator layout actually? pls dont mind.., I m little new to android dev.
  • Jemshit Iskenderov
    Jemshit Iskenderov over 6 years
    "View capable of nested scrolling" is important i guess, if you disable nestedScrolling on recyclerView it does not work
  • Ted Hopp
    Ted Hopp over 6 years
    The design support library already defines that string resource. There is nothing gained by redefining it in your own resources.
  • Ranjit
    Ranjit over 6 years
    @eRaisedToX Its nothing but a FrameLayout with some adding features..Check it once developer.android.com/reference/android/support/design/widge‌​t/…
  • Ranjit
    Ranjit over 6 years
    May be you are right .I forgot , but I faced problem and resolved it after adding this in string.xml.
  • Surjit Singh
    Surjit Singh over 6 years
    @Jemshit Iskenderov is right never set recyclerView.setNestedScrollingEnabled(false); you are just using recycler after AppBarLayout, or your recycler view is not inside NestedScrollView.
  • btraas
    btraas about 3 years
    Also SwipeRefreshLayout