9

I have viewpager2 with 4 fragments. 3 of them have SwipeRefreshLayout to refresh async task data in particular fragments.

When using SwipeRefreshLayout and viewpager2 the gestures are somehow conflicting. ie. swype down to refresh makes screen so sensitive, that a little move to left or right also makes page screen change and refresh icon is freezing or the processis unfinished.

my goal is to make gestures independent, so for example when i start to swype down SwipeRefreshLayout, then vp2 is disabled so it it is not interfere with SRL.

This was not happening when using standard viewpager with SwipeRefreshLayout, gestures were not conflicting, but I need to use "setUserInputEnabled" in VP2. any idea how to mitigate this behaviour and should i mitigate it at SwipeRefreshLayout level or within viepager2 code?

B.Ondrej
  • 381
  • 4
  • 14

3 Answers3

7

It looks problem is resolved when I added to my scrollview:

android:nestedScrollingEnabled="true"

Final code of the fragment layout then looks like this:

<?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/some_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/activity_background"
tools:context="some_fragment_name">

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:fillViewport="true"
    android:nestedScrollingEnabled="true" <<<<------ HERE the change
    android:id="@+id/some_id">

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/sensors_relative_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context="some_package_name">

    <TextView
        android:id="@+id/some_id"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:background="@android:color/white"
        android:gravity="center"
        android:textColor="@android:color/black"
        android:textStyle="bold"
        android:layout_marginTop="5sp"
        android:layout_marginLeft="5sp"
        android:layout_marginRight="5sp"
        android:textSize="20sp" />

...

B.Ondrej
  • 381
  • 4
  • 14
  • 1
    Have you able to resolve it by adding the property to `ScrollView`? What if I don't have parent `ScrollView` in my layout, but experiencing exactly the same issue. – romandrahan Sep 04 '19 at 09:14
  • UPD. Was able to resolve it too with ``` args.object.android.setNestedScrollingEnabled(true) ``` For `ListView` inside `SwipeRefreshLayout`, and for `ViewPager`. – romandrahan Sep 04 '19 at 09:39
  • Yes you can add it to ScrollView property and it works. Since I have used that, I have just super-nice scrolling behaviour – B.Ondrej Sep 05 '19 at 10:05
  • What if you only have a `RecyclerView` or `SwipeRefreshLayout` as the child? Setting `nestedScrollingEnabled="true"` does not work. I can still swipe the pages (horizontally) even if I started a refresh (vertical swipe) or a vertical scroll... – l33t Feb 06 '20 at 18:54
  • @l33t have you tried with the last version of SwipeRefreshLayout? see the answer I just wrote – FlorianT May 22 '20 at 07:54
6

EDIT: Update as 1.1.0 has been released on July 22, 2020

The problem was due to a bug in SwipeRefreshLayout, which has been resolved by Version 1.1.0. To use it, just upgrade to that version by adding the following line in the dependencies of your Gradle file:

implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'

See issueTracker for the bug history: [ViewPager2] SwipeRefreshLayout should not ignore requestDisallowInterceptTouchEvent. Note that there's also a workaround described there (extending SwipeRefreshLayout and overriding "requestDisallowInterceptTouchEvent").

FlorianT
  • 1,147
  • 11
  • 16
3

If you have RecyclerView in SwipeRefreshLayout you need to wrap RecyclerView in FrameLayout aur any other layout and set nestedScrollingEnabled="true" on Layout not set on RecyclerView.

<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
    android:id="@+id/swipeRefreshLayout"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:nestedScrollingEnabled="true">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/media_recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    </FrameLayout>

</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
Saeed Younus
  • 279
  • 3
  • 4