7

I have a vertical scrolling ViewPager2 and the last children contains a RecyclerView scrolling on the same direction.

This is causing a conflicting behaviour, the ViewPager2 always steal the scroll event when I am at the page containing this RecyclerView. The only way to make the scroll inside the RecyclerView is if I scroll really slow, if I make it fast, like a swipe event the ViewPager2 gets scrolled and changes the page.

Currently I'm doing a fix that involves disabled the user interaction changing the flag isUserInputEnabled to false when the page of the ViewPager2 changes to this page that contains the RecyclerView, but a generic solution from the framework would be welcome :)

extmkv
  • 1,991
  • 1
  • 18
  • 36
  • Try to put your RecyclerView inside a `` [NestedScrollView](https://developer.android.com/reference/android/support/v4/widget/NestedScrollView) – blaffie Oct 16 '19 at 15:27
  • 3
    ^ However, keep in mind that in doing so, your RecyclerView can no longer recycler views and will resort to a mere widget inflating all its content at once, for it no longer has control over the dimensions and it must delegate this to the NestedScrollView, which knows nothing about recycling a view. – Martin Marconcini Oct 16 '19 at 15:52

4 Answers4

11

I had a similar issue to yours and I found the answer via the official documentation.

I would suggest NOT to place your RecyclerView within a NestedScrollView simply for the reason Martin Marconcini answered previously. This causes the RecyclerView to create ViewHolders for every single data item, with no regards to recycling them. That is obviously very inefficient.

Instead, Google provided a solution in their ViewPager2 samples where they created a generic wrapper class called NestedScrollableHost that you simply add to your project. Then you can wrap that RecyclerView with it, similar to below, to handle the intercepted touch/swipe events:

<NestedScrollableHost
            android:layout_width="match_parent"
            android:layout_height="match_parent">

        <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/my_recycler_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical" />

    </NestedScrollableHost>

As noted by the documentation, this only works for immediate children of the ViewPager2, which in your case should work just fine.

Hope that helps!

Martin Marconcini
  • 26,875
  • 19
  • 106
  • 144
Calvin Rai
  • 816
  • 1
  • 8
  • 17
  • anybody can provide java version of NestedScrollableHost class? – Ali Zarei Apr 04 '20 at 09:28
  • 3
    @AliZarei I made a Java version of it, you can find it here https://gist.github.com/KhaledAlharthi/e7e52cdf689295abb76b9437e1e02228 – Khaled Apr 12 '20 at 15:03
  • 1
    To future reader, do not use the java version above it is not the same as the Kotlin version and does not work properly on older devices. Save yourself. – Bitwise DEVS May 19 '21 at 18:55
2

edit child of ViewPager as RecyclerView

(binding.viewPager.getChildAt(0)as RecyclerView).isNestedScrollingEnabled = false

it's worked for me

0

Put your recyclerview inside NestedScrollView and set below property on recyclerview and

android:nestedScrollingEnabled="false"

Try this or manage touch event on recyclerview

vijay_s30
  • 84
  • 1
  • 6
0

I will stop scroll of viewpaper2:

mviewpager.setUserInputEnabled(false);
RusArtM
  • 1,116
  • 3
  • 15
  • 22