Edgar Chaparro from https://unsplash.com/photos/UJRDiuvp7tc

Prevent Scroll Conflicts in Nested ViewPager

Once upon a time you are faced with a design where the Banner is inside Tab Layout, then this banner will conflict if you want to move it, most likely what will shift is the parent layout, not the Banner. There are many solutions, maybe you will prefer to use Recyclerview and customize touch listener or snap. But even though this nested Viewpager is really annoying, not many articles discuss this trivial thing.

It’s simple, disable the parent viewpager when the touch banner is triggered.

But, is not easy as it seems, particularly it’s just disabled when nested Viewpager slide, lets sample below, i create two adapter one is using Recycler Adapter view and the other one using FragmentStateAdapter. Why I using this, first my banner only contain image, its not necessary if put Fragment if only contain image and text better just use item view.

Simple Fragment Adapter FragmentAdapter.kt, this Adapter contains Fragments

Below is Fragment class, this class will inflate and show inside View Pager. First, because it's just a sample I just only create two Fragment with only one View Layout (I am too lazy to create another one, just reuse and differentiate with position). The first fragment will show Nested Viewpager, but the second fragment is not visible, to prove the view pager its work when sliding inside Fragment.

We need main layout to inflate those ViewPager it can be Main Activity or Fragment but I use fragment here because they already exist in my experiment project and are tied with MainActivity. Please Refer in and function, we create setVpEnable function to give access nested fragment to get ViewPager reference so we can set enable or disable in child layout. As you can see ViewPager had a function to enable nested scrolling but it doesn't work after all.

After That, you should create an adapter for Banner, This Adapter using Recyclerview different from the first one. This Banner is not showing Image instead show Background Color, which distinguishes one banner from another. We call setTouchlistener inside bind function to notify touch from the user, if user touches the view then it will notify parent Fragment to disable parent ViewPager. Where does the listener come from, it comes from constructor Adapter .

Okay All Done, The Main Point to prevent conflict Nested ViewPager is;

  • Listen onTouch inside nested ViewPager, if Touch happens in this item view (Image view) it will disable parent ViewPager.
  • registerOnPageChangeCallback in parent fragment after instantiate nested Viewpager, Please disable parent ViewPager with validation, it means the nested ViewPager already finish dragging.

Android Developer and Learner.