Has anyone figured out a way to get recyclerviews, AppbarLayouts and SwipeRefreshLayout to work together on 23.2 yet? I am using a pretty standard method I think, but the swiperefreshlayout keeps grabbing the scroll gesture when trying to move up the recyclerview.
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="?attr/toolbar_theme"
app:layout_scrollFlags="scroll|enterAlways"
android:elevation="4dp" />
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="@+id/fragment_container"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--fragment goes here -->
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
with the following inside it
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/swipe_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/window_background">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_marginTop="-4dp"
android:layout_marginBottom="-8dp"
android:elevation="17dp"
android:indeterminate="true"
android:visibility="invisible" />
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
</FrameLayout>
</android.support.v4.widget.SwipeRefreshLayout>
If you put a View that doesn't implement
ScrollingView
or isn't anAbsListView
intoSwipeRefreshLayout
,SwipeRefreshLayout#canChildScrollUp()
always returns false.So by using a
FrameLayout
inside ofSwipeRefreshLayout
you have two issues:SwipeRefreshLayout
doesn't accept nested scroll operations of descendant views (seeSwipeRefreshLayout#onStartNestedScroll(View, View, int)
). This causes the issues withCoordinatorLayout
/AppBarLayout
.The
SwipeRefreshLayout
handles touch events itself as long as its child cannot scroll up or there is no nested scroll in progress (seeSwipeRefreshLayout#onInterceptTouchEvent(MotionEvent)
andSwipeRefreshLayout#onTouchEvent(MotionEvent)
). This means the spinner is displayed when "touch moving down".You can fix this by using your own
SwipeRefreshLayout
, which overwritesSwipeRefreshLayout#onStartNestedScroll(View, View, int)
. This way nested scrolls are accepted even if the direct child view can't scroll up:BTW if you look at
SwipeRefreshLayout
's code in 23.1.1 you'll see, that the canChildScrollUp() check was removed but was added again in 23.2.0. I also removed the check for!mReturningToStart
, becausemReturningToStart
is alwaysfalse
.attrs.xml
layout.xml
ImprovedSwipeLayout.java
It's from http://nerd-is.in/2014-09/add-multi-child-view-in-swiperefreshlayout/
Create a View extend SwipeRefreshLayout and custom canChildScrollUp.
Faced same issue after updating to
23.2.0
. It's an old-new bug which was fixed in23.1.1
and appears again in23.2.0
.In my case I downgrade to
23.1.1
and everithing is OK again. So we should wait for new version of libs or use workarounds with overridingSwipeRefreshLayout
.Here is link to google bugtracker: RecyclerView v23.2.0 - doesn't play nicely with SwipeRefreshLayout