AppBarLayout with FrameLayout container as scrolling content doesn't work

Replace your FrameLayout with android.support.v4.widget.NestedScrollView

NestedScrollView is just like ScrollView, but it supports acting as both a nested scrolling parent and child on both new and old versions of Android. Nested scrolling is enabled by default.

Link to doc


Using FrameLayout as child of CoordinatorLayout works quite well. The toolbar is collapsing like it's supposed to. I had a problem in the beginning, when I used outdated libraries.

Here are the gradle dependencies I'm using right now:

compile 'com.android.support:appcompat-v7:22.2.1'
compile 'com.android.support:cardview-v7:22.2.0'
compile 'com.android.support:recyclerview-v7:22.2.0'
compile 'com.android.support:design:22.2.0'

I'm using FrameLayout with the attribute app:layout_behavior="@string/appbar_scrolling_view_behavior" as a child of CoordinatorLayout in an activity's layout. The FrameLayout serves as container for fragments. My fragment layouts' root elements are either a RecyclerView or a NestedScrollView.

Here is the layout of the activity:

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

    <FrameLayout
            android:id="@+id/..."
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            />

    <android.support.design.widget.AppBarLayout
            android:layout_height="192dp"
            android:layout_width="match_parent"
            >
        <android.support.design.widget.CollapsingToolbarLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_scrollFlags="scroll|exitUntilCollapsed"
                >
            <ImageView
                    android:id="@+id/.."
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:fitsSystemWindows="true"
                    android:scaleType="centerCrop"
                    android:src="@drawable/..."
                    app:layout_collapseMode="parallax"/>
            <android.support.v7.widget.Toolbar
                    android:id="@+id/toolbar_sessions"
                    android:layout_height="?attr/actionBarSize"
                    android:layout_width="match_parent"
                    app:layout_collapseMode="pin"
                    />
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

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

My first fragment's layout looks like this:

<android.support.v7.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:scrollbars="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="..."
    />

My second fragment's layout looks like this:

<android.support.v4.widget.NestedScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="..."
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="..."
    >
...
</android.support.v4.widget.NestedScrollView>

The reason for that behaviour is that the Framelayout doesn't specify a Behaviour. The CoordinatorLayout relies on the child view to handle the Behaviour.

You can read at the bottom here

http://android-developers.blogspot.in/2015/05/android-design-support-library.html

It states that

CoordinatorLayout and custom views

One thing that is important to note is that CoordinatorLayout doesn’t have any innate understanding of a FloatingActionButton or AppBarLayout work - it just provides an additional API in the form of a Coordinator.Behavior, which allows child views to better control touch events and gestures as well as declare dependencies between each other and receive callbacks via onDependentViewChanged().

Views can declare a default Behavior by using the CoordinatorLayout.DefaultBehavior(YourView.Behavior.class) annotation,or set it in your layout files by with the app:layout_behavior="com.example.app.YourView$Behavior" attribute. This framework makes it possible for any view to integrate with CoordinatorLayout.

Edit: Although FrameLayout is not a custom view, it doesnt specify a behaviour which CoordinateLayout seeks.