168

Is it possible to enable-disable swiping in new android viewpager2 component?

AskNilesh
  • 67,701
  • 16
  • 123
  • 163
murgupluoglu
  • 6,524
  • 4
  • 33
  • 43

7 Answers7

353

Now it is possible to enable-disable swiping viewpager2 using Version 1.0.0-alpha02

Use implementation 'androidx.viewpager2:viewpager2:1.0.0-alpha02'

Version 1.0.0

New features

  • Ability to disable user input (setUserInputEnabled, isUserInputEnabled)

API changes

  • ViewPager2 class final

Bug fixes

  • FragmentStateAdapter stability fixes

SAMPLE CODE to disable swiping in viewpager2

myViewPager2.setUserInputEnabled(false);

SAMPLE CODE to enable swiping in viewpager2

myViewPager2.setUserInputEnabled(true);
murgupluoglu
  • 6,524
  • 4
  • 33
  • 43
AskNilesh
  • 67,701
  • 16
  • 123
  • 163
16

If you are using Android Data Binding you can simply disable it your layout xml file.

app:userInputEnabled="@{false}"
Dennis
  • 209
  • 2
  • 5
11
viewPager2.setUserInputEnabled(false);
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
Yamini
  • 732
  • 7
  • 11
6

Under the hood ViewPager2 works with RecyclerView for inflating the fragment views, but the RecyclerView is hidden so they make it more idiot proof.

 val rv : RecyclerView = viewPager.getChildAt(0) as RecyclerView
 rv.layoutManager = NonScrollingLayoutManager( rv.context, rv.layoutManager as LinearLayoutManager)

Hacky way is to get the child at position zero which is the RecyclerView and disable scrolling in the layout manager, by wrapping the layout manager:

inner class NonScrollingLayoutManager(context: Context, val layoutManager: LinearLayoutManager) :
    LinearLayoutManager(context, layoutManager.orientation, layoutManager.reverseLayout) {

    override fun canScrollVertically(): Boolean  = layoutManager.orientation == HORIZONTAL


    override fun canScrollHorizontally(): Boolean  =  layoutManager.orientation == VERTICAL

}

Please beware that if the API changes the layout manager used for the RecyclerView, i.e they move away from the LinearLayoutManager this wont work and it will need some methods overriden and ensure super methods are called.

Second approach is subclass the ViewPager2 which is ViewGroup and then do the magic in intercepting touch events, before they are dispatched to the child views (as you would guess the RecyclerView) and be careful not to prevent clicks.

Nikola Despotoski
  • 49,966
  • 15
  • 119
  • 148
6

in kotlin just use viewPager2.isUserInputEnabled = false

Mahmoud Zaher
  • 559
  • 6
  • 6
1

Yes it is possible.

mViewPager2.setUserInputEnabled(false); //disables swipe

mViewPager2.setUserInputEnabled(true); //enables swipe

We can disable and enable based on tabs, as shown in below code

ViewPager2 mViewPager2 = findViewById(R.id.view_pager);
        mViewPager2.setOffscreenPageLimit(adapter.getItemCount() - 1);
        mViewPager2.setAdapter(adapter); 


        TabLayout tabLayout  = findViewById(R.id.sliding_tabs);
        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                //do stuff here
                if(tab.getPosition() == 0){
                    **//ToDisable**
                    mViewPager2.setUserInputEnabled(false);
                }else{
                    **//ToEnable**
                    mViewPager2.setUserInputEnabled(true);
                }

            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });
tanni tanna
  • 544
  • 4
  • 12
0

simply use myViewPager2.setUserInputEnabled(false); // in java myViewPager2.isUserInputEnabled = false // in kotlin to disable manually scrolling by user on swiping