Skip to content
Advertisement

How to fix Scrolling issue of horizontal ViewPager2 and RecyclerView that are inside a vertical RecyclerView?

I have a RecyclerView (say, rootRecyclerView) that can have different kinds of rows depending on some API response. I implemented one of them is a horizontal ViewPager2 and another one is implemented with horizontal RecyclerView (say, childRecyclerView).

The rootRecyclerView swipes vertically whereas the viewPager2 and childRecyclerView swipes horizontally.

The Problem:

When I swipe on the screen, if the swipe is on the the viewPager2 or childRecyclerView, the swipe MUST go perfectly straight horizontally. Otherwise, they won’t scroll horizontally; the swipe is taken by the rootRecyclerView and so the you would see vertical movement.

So, this happens because your thumb would move in a curved/circular direction creating movement in both the X axis and Y axis, and the so the rootRecyclerView intercepts the swipe creating this unpleasant user experience.

I did try to solve the issue, such as adding an OnItemTouchListener to the childRecyclerView like this:

JavaScript

It solves the problem only for the childRecyclerView, but I could not solve it for the ViewPager2.

I have also tried to use GestureDetector as described in this answer link, and some other combinations of code, but I could not make it work.

Could anyone help me?

Advertisement

Answer

Okay, so after some research, I came to the conclusion of substituting my ViewPager2 with a recyclerView that will ‘behave like’ a viewPager :/ .

First I replaced my viewPager2 with a horizontal recyclerView. To make it behave like a viewpager, use SnapHelper.

JavaScript

After that, you have to add an OnItemTouchListener and override onInterceptTouchEvent just like the code segment in my question:

JavaScript

Optional:

In viewPager2, you can get the current focus with getCurrentItem(), but since we have replaced out viewpager2 with recyclerview, we don’t have that method. So, we need to implement our own equivalent version. If you are a Kotlin guy, you can directly jump to the reference 2 and skip this part. Here is the java version if you need, I’ll skip the explanation though. Create SnapHelperExt.java

JavaScript

Next create an interface OnSnapPositionChangeListener as our listener :

JavaScript

After that, create SnapOnScrollListener.java:

JavaScript

Finally, use it in this way:

JavaScript

References:

  1. create-viewpager-using-recyclerview
  2. detecting-snap-changes-with-androids-recyclerview
Advertisement