Scrolling down triggers refresh instead of revealing the toolbar

Longi picture Longi · Jun 14, 2015 · Viewed 7.2k times · Source

I started using the new CoordinatorLayout and I ran into this issue:

demo

As you can see when I try to scroll down when the toolbar is partially visible and the recylcerview is at the top position it triggers the refresh event instead of pulling down the toolbar. The user has to scroll up than down again to reveal it.

Layout XML looks something like this: activity_main.xml:

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

    <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.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                style="@style/customActionBar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="?attr/colorPrimary"
                android:minHeight="?attr/actionBarSize"
                app:layout_scrollFlags="scroll|enterAlways"/>

        </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>

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="@android:color/white"
        app:headerLayout="@layout/navigation_drawer_header"
        app:menu="@menu/navigation_items" />

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

fragment_main.xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swipe_refresh"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clipToPadding="false"
            android:padding="8dp"
            android:scrollbars="none" />

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

</FrameLayout>

Ther SwipeRefreshLayout is in a FrameLayout becuase there are more elements in the fragment in my app.

Any help would be appreciated.

Answer

Kosh picture Kosh · Aug 26, 2015

maybe too late but it might help any new comers, i came up with an easy solution for that. by creating custom class that extends SwipeRefreshLayout you can use it anywhere where AppBaLayout exists follow code below

    public class MySwipeLayout extends SwipeRefreshLayout implements AppBarLayout.OnOffsetChangedListener {
        private AppBarLayout appBarLayout;

        public MySwipeLayout(Context context) {
            super(context);
        }

        public MySwipeLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
        }

        @Override
        protected void onAttachedToWindow() {
            super.onAttachedToWindow();
            if (getContext() instanceof Activity) {
                appBarLayout = (AppBarLayout) ((Activity) getContext()).findViewById(R.id.appbar);
                appBarLayout.addOnOffsetChangedListener(this);
            }
        }

        @Override
        protected void onDetachedFromWindow() {
          if(appBarLayout!=null){
            appBarLayout.removeOnOffsetChangedListener(this);
            appBarLayout = null;
          }
          super.onDetachedFromWindow();
        }

        @Override
        public void onOffsetChanged(AppBarLayout appBarLayout, int i) {
            this.setEnabled(i == 0);
        }
    }