AppBarLayout with FrameLayout container as scrolling content doesn't work

I’m trying to use the newest design library to make my toolbar hide/show on scroll. My issue is the scrolling content I have is in the fragment, I’m just injecting it into the FrameLayout container and it doesn’t work. Here’s my activity:

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.design.widget.CoordinatorLayout
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

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

        <include layout="@layout/layout_toolbar" />

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

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

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

<FrameLayout
    android:id="@+id/navigation_drawer_container"
    android:layout_width="@dimen/navigation_drawer_width"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    tools:layout="@layout/fragment_nav_drawer_anon" />

  • Write % in strings.xml of android
  • Fully functional android data grid
  • Android Google maps transparency
  • Execute http request in parallel with Retrofit 2
  • Android: Call super() at the beginning or end of onStart(), onStop(), onDestroy() in activity?
  • How to start activity after unlock btn press & before unlock screen appear?
  • and my fragment:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    
    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/pull_to_refresh"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <ListView
            android:id="@android:id/list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </android.support.v4.widget.SwipeRefreshLayout>
    
    <TextView
        android:id="@android:id/empty"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textSize="18sp"
        android:fontFamily="sans-serif"
        android:color="@color/dark_grey"
        android:padding="60dp"/>
    

    and toolbar:

    <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimary"
    android:minHeight="?attr/actionBarSize"
    app:layout_scrollFlags="scroll|enterAlways"
    style="@style/Widget.MyApp.ActionBar" />
    

    I’m following official doc and this demo, and still can’t figure out how to make it work.

    Related posts:

    How to use OpenCV to process image so that the text become sharp and clear?
    Android RX - Observable.timer only firing once
    GCM push notifications not working if the app is closed in some devices
    End animation event android
    Android 4.1.1/4.1.2 Date Picker Galaxy S3
    Ionic/HTML5 - Decimal Keyboard Input?
  • Android Spinner.setSelection() doesn't work
  • Parse and Play a .pls file in Android
  • Get caps lock state in Android
  • Mask an EditText with Phone Number Format NaN like in PhoneNumberUtils
  • How (and where) to fix android.os.BadParcelableException: ClassNotFoundException when unmarshalling: RecyclerView$SavedState?
  • How to make a new line or tab in <string> XML (eclipse/android)?
  • 10 Solutions collect form web for “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

    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.

    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>
    

    In my app it works only with RecyclerView. Maybe you should use RecyclerView instead of ListView.

    It’s a good question. I too had the same.

    Your container FrameLayout is defined right the problem lies with the Fragment. The Fragment should have RecyclerView & not ListView as it is now deprecated.

    Example:

    <android.support.v7.widget.RecyclerView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipToPadding="false"
        android:paddingTop="@dimen/activity_vertical_margin"/>
    

    I use the same structure in my app & it works perfect.

    You can achieve scrolling with Framelayout inside your CoordinatorLayout. For it you have to use app:layout_behavior="@string/appbar_scrolling_view_behavior" inside your frameLayout as well as inside the scrolling view with which you want this collapsing effect.

    For ex- If you are inflating RecyclerView inside your frameLayout, then you have to use app:layout_behavior="@string/appbar_scrolling_view_behavior" inside your recyclerrView also.

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout 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:orientation="vertical">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
        />
    </Relativelayout>
    

    or,

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout 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:orientation="vertical">
     <android.support.v4.widget.NestedScrollView
               android:layout_width="match_parent"
               android:layout_height="fill_parent"
            android:layout_above="@+id/bNext"
            android:fillViewport="true"
               android:scrollbars="none"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">
    <!--  your content -->
    </android.support.v4.widget.NestedScrollView>
    </Relativelayout>
    

    Thus, using this process you can achieve scrolling with frameLayout whether it contains recycler or nestedScrollview.

    ListView does not implement NestedScrollingChild so it does not work.

    RecyclerView does, so it can propagate the scroll to the NestedScrollingParent (the CoordinatorLayout).

    You only need to replace

    FrameLayout

    to

    android.support.v4.widget.NestedScrollView

    in this way:

    <android.support.design.widget.CoordinatorLayout
        android:id="@+id/root_coordinator"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <android.support.design.widget.AppBarLayout
            android:id="@+id/app_bar_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <android.support.design.widget.CollapsingToolbarLayout
                android:id="@+id/collapsing_toolbar_layout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:contentScrim="?attr/colorPrimary"
                app:layout_scrollFlags="scroll|enterAlways">
    
                <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="192dp"
                    android:scaleType="centerCrop"
                    android:src="@drawable/header"
                    app:layout_collapseMode="parallax" />
    
                <android.support.v7.widget.Toolbar
                    android:id="@+id/app_bar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                    app:layout_collapseMode="pin" />
    
            </android.support.design.widget.CollapsingToolbarLayout>
    
        </android.support.design.widget.AppBarLayout>
    
        <!-- This was before FrameLayout -->
        <android.support.v4.widget.NestedScrollView
            android:id="@+id/content_frame"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">
        </android.support.v4.widget.NestedScrollView>
    
        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|right"
            android:layout_margin="16dp"
            android:src="@drawable/ic_drawer_alertas"
            app:borderWidth="0dp"
            app:fabSize="mini" />
    </android.support.design.widget.CoordinatorLayout>
    
    
    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_drawer"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/drawer_header"
        app:itemIconTint="@color/colorAccent"
        app:itemTextColor="@color/colorSecondaryText"
        app:menu="@menu/menu_main" />
    

    You must add behavior to the scroll view:

    <android.support.v4.widget.SwipeRefreshLayout
        android:layout_marginTop="5dp"
        android:id="@+id/swipe_main"
        android:enabled="false"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
    <com.marshalchen.ultimaterecyclerview.UltimateRecyclerView
        android:id="@+id/rvUserProfile"
        app:recyclerviewEmptyView ="@layout/ev_home"
        app:recyclerviewClipToPadding="false"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></com.marshalchen.ultimaterecyclerview.UltimateRecyclerView>
    </android.support.v4.widget.SwipeRefreshLayout>
    

    Move the app:layout_scrollFlags="scroll|enterAlways" from the toolbar to the Framelayout. Sorry for being late.

    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.