mrobinson7627 mrobinson7627 - 1 year ago 152
Android Question

Android CoordinatorLayout Behaviour with complex layout

I have a simple layout that is a

CoordinatorLayout
containing a
Toolbar
in an
AppBarLayout
and a
RecyclerView
. To allow for a progress bar while content is loaded into the
RecyclerView
I've wrapped it in a
FrameLayout
alongside a
ProgressBar
which I've included from another file. When the content is loading the
ProgressBar
is set to
VISIBLE
and when it's finished it's set to
GONE
, showing the
RecyclerView
. I'd like to use a
ScrollingViewBehavior
so that when I scroll my
RecyclerView
the
Toolbar
is hidden. I've tried adding it to the
FrameLayout
and the
RecyclerView
and neither seems to work.

What do I have to do to get the behavior I am looking for? Do I need to make a new
ViewGroup
or something like that in order to show/hide the
ProgressBar
and define a new
Behavior
for that, or is there something simpler?

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">

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

<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:theme="@style/ToolbarTheme"
android:background="?attr/colorPrimary"/>
</android.support.design.widget.AppBarLayout>

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:id="@+id/recycler_view" />

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

</FrameLayout>

<include layout="@layout/floating_action_button"/>
</android.support.design.widget.CoordinatorLayout>

Answer Source

I have almost the same setup you do, but I've included two progress bars. One appears when the activity is loaded, and covers the whole thing. The second one appears on a swipe refresh and only replaces the RecyclerView (well, actually the RecyclerView's parent SwipeRefreshLayout).

<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:focusableInTouchMode="true">

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

    <android.support.design.widget.CoordinatorLayout
        android:id="@+id/coordinator_layout"
        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:fitsSystemWindows="false">

        <android.support.design.widget.AppBarLayout
            android:id="@+id/app_bar"
            android:layout_width="match_parent"
            android:layout_height="@dimen/app_bar_height"
            android:fitsSystemWindows="false"
            android:theme="@style/AppTheme.AppBarOverlay">

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

                <android.support.v7.widget.Toolbar
                    android:id="@+id/toolbar_landing_page"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    app:layout_collapseMode="pin"
                    app:popupTheme="@style/AppTheme.PopupOverlay"/>

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

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

        <android.support.v4.widget.SwipeRefreshLayout
            android:id="@+id/swipe_refresh"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="@dimen/landing_page_top_margin"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">

            <android.support.v7.widget.RecyclerView
                android:id="@+id/recycler_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>

        </android.support.v4.widget.SwipeRefreshLayout>
    </android.support.design.widget.CoordinatorLayout>
</RelativeLayout>

And my progress bar is just:

<ProgressBar
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/loading_progress"
    style="@android:style/Widget.ProgressBar.Inverse"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:visibility="gone"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

When it's time to show the progress bar I set it to View.VISIBLE and the SwipeRefreshLayout (or the CoordinatorLayout for when the Activity is loaded) to View.GONE. Then reverse the VISIBLE and GONE when the data is loaded.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download