How to disable or enable viewpager swiping in android
Asked Answered
C

9

83

What i am trying to do: I am trying to Enable/disable swiping in pager programatically when the program is running

Ex: When on the flow if i check for a condition and if it returns true enable swiping, and if condition returns false disable swiping.


Solution i am using is this one

public class CustomViewPager extends ViewPager {

private boolean enabled;

public CustomViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.enabled = true;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (this.enabled) {
        return super.onTouchEvent(event);
    }

    return false;
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    if (this.enabled) {
        return super.onInterceptTouchEvent(event);
    }

    return false;
}

public void setPagingEnabled(boolean enabled) {
    this.enabled = enabled;
} }

Then select this instead of the builtin viewpager in XML

<mypackage.CustomViewPager 
android:id="@+id/myViewPager" 
android:layout_height="match_parent" 
android:layout_width="match_parent" />

You just need to call the "setPagingEnabled" method with "false" and users won't be able to swipe to paginate.


Problem with above methodology: i cannot set the property on the flow, I:e .... I either can enable swiping or disable swiping. But i cannot do this based on condition


Question:

  1. Can i achieve my goal in some-other way, if so what is it ?
  2. Or is this not possible ?
Covenanter answered 4/4, 2015 at 2:54 Comment(3)
Possible duplicate of How do disable paging by swiping with finger in ViewPager but still be able to swipe programmatically?Amiamiable
Would not it be possible to set the property on the flow with DataBinding ?Uncircumcision
Try to use https://mcmap.net/q/151252/-is-it-possible-to-disable-scrolling-on-a-viewpagerVoelker
A
65

Disable swipe progmatically by-

    final View touchView = findViewById(R.id.Pager); 
    touchView.setOnTouchListener(new View.OnTouchListener() 
    {         
        @Override
        public boolean onTouch(View v, MotionEvent event)
        { 
           return true; 
        }
     });

and use this to swipe manually

touchView.setCurrentItem(int index);
Ariellearies answered 4/4, 2015 at 4:13 Comment(7)
This still lets the viewpager to be partially swiped (like 1%) before it stops. It looks ugly.Jerkwater
His solution works, it is just incomplete. You should also override onInterceptTouchEvent(MotionEvent event) too. This will give you the look you desire without the 1%Blumenfeld
Unable to overide that methodFantasist
it works but when it enabled , swiping is very bad and slowCostrel
It not works, try to swipe your view pager repeatedly, and you can see your another view shown !!. you have to set onInterceptTouchEvent too.Cecrops
this is absulutally wrong solution, why so many stars. It indeed looks ugly, with swipe of 1%. Probably, we should extend viewpager, and override onInterceptTouchEventRhoades
If you override onInterceptTouchEvent() (return true, for example), the views inside ViewPager will not receive input. Which is not what you want in most cases.Dorri
D
82

Best solution for me. -First, you create a class like this:

public class CustomViewPager extends ViewPager {
  private Boolean disable = false;
  public CustomViewPager(Context context) {
      super(context);
  }
  public CustomViewPager(Context context, AttributeSet attrs){
      super(context,attrs);
  }
  @Override
  public boolean onInterceptTouchEvent(MotionEvent event) {
     return !disable && super.onInterceptTouchEvent(event);
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
     return !disable && super.onTouchEvent(event);
  }

  public void disableScroll(Boolean disable){
      //When disable = true not work the scroll and when disble = false work the scroll
      this.disable = disable;
  }
}

-Then change this in your layout:<android.support.v4.view.ViewPager for this<com.mypackage.CustomViewPager

-Finally, you can disable it:view_pager.disableScroll(true); or enable it: view_pager.disableScroll(false);

I hope that this help you :)

Dermatoid answered 15/6, 2017 at 16:26 Comment(6)
Thanx Alberto :)Morette
Also don't forget to call viewPager.invalidate() method after calling disable scrolling method, because of that it instantly disable swipe over.Carmina
With this solution the views inside ViewPager will not receive any input if disable == true. Overriding onInterceptTouchEvent() is not the correct solution.Dorri
instead of Boolean I'd rather use boolean here.Feller
Thanks. Your answer helped me to improve a working feature.Dorcy
For Viewpager2 you don't need custom class you can simply disable scroll by using myViewPager2.setUserInputEnabled(false);Chak
A
65

Disable swipe progmatically by-

    final View touchView = findViewById(R.id.Pager); 
    touchView.setOnTouchListener(new View.OnTouchListener() 
    {         
        @Override
        public boolean onTouch(View v, MotionEvent event)
        { 
           return true; 
        }
     });

and use this to swipe manually

touchView.setCurrentItem(int index);
Ariellearies answered 4/4, 2015 at 4:13 Comment(7)
This still lets the viewpager to be partially swiped (like 1%) before it stops. It looks ugly.Jerkwater
His solution works, it is just incomplete. You should also override onInterceptTouchEvent(MotionEvent event) too. This will give you the look you desire without the 1%Blumenfeld
Unable to overide that methodFantasist
it works but when it enabled , swiping is very bad and slowCostrel
It not works, try to swipe your view pager repeatedly, and you can see your another view shown !!. you have to set onInterceptTouchEvent too.Cecrops
this is absulutally wrong solution, why so many stars. It indeed looks ugly, with swipe of 1%. Probably, we should extend viewpager, and override onInterceptTouchEventRhoades
If you override onInterceptTouchEvent() (return true, for example), the views inside ViewPager will not receive input. Which is not what you want in most cases.Dorri
A
22

In your custom view pager adapter, override those methods in ViewPager.

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    // Never allow swiping to switch between pages
    return false;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    // Never allow swiping to switch between pages
    return false;
}

And to enable, just return each super method:

super.onInterceptTouchEvent(event) and super.onTouchEvent(event).

Aforementioned answered 13/10, 2016 at 21:17 Comment(0)
T
6

For disabling swiping

mViewPager.beginFakeDrag();

For enable swiping

if (mViewPager.isFakeDragging()) mViewPager.endFakeDrag();

Trant answered 23/11, 2018 at 9:57 Comment(5)
will have this issue github.com/JakeWharton/ViewPagerIndicator/issues/412Prestissimo
Can u pls elaborate your query?Trant
I try to use this solution, but it'll throw NullPointerException when calling endFakeDrag.Prestissimo
try to use a condition like. if (mViewPager.isFakeDragging()) mViewPager.endFakeDrag();Trant
This doesn't stop swiping. It just makes it uglySpiegelman
B
6

If you want to extend it just because you need Not-Swipeable behaviour, you dont need to do it. ViewPager2 provides nice property called : isUserInputEnabled

Blinny answered 29/8, 2020 at 8:5 Comment(0)
A
5

To disable swiping in viewpager2 use

viewPager2.setUserInputEnabled(false);

To enable swiping in viewpager2 Use

viewPager2.setUserInputEnabled(true);
Anthesis answered 9/9, 2021 at 5:34 Comment(1)
viewPager2.isUserInputEnabled = false // Disable swiping...Interest
T
3

In my case, the simplified solution worked fine. The override method must be in your custom viewpager adapter to override TouchEvent listeners and make'em freeze;

@Override
public boolean onTouchEvent(MotionEvent event) {
    return this.enabled && super.onTouchEvent(event);

}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    return this.enabled && super.onInterceptTouchEvent(event);

}
Twodimensional answered 11/9, 2017 at 8:14 Comment(3)
provide an explanation about the solution providedDiaconal
@AnanthaRajuC provided :)Twodimensional
With this solution thye views inside ViewPager will not receive any input if this.enabled == false. Overriding onInterceptTouchEvent() is not the correct solution.Dorri
V
2

I found another solution that worked for me follow this link

https://mcmap.net/q/151252/-is-it-possible-to-disable-scrolling-on-a-viewpager

It basically overrides the method canScrollHorizontally to disable swiping by finger. Howsoever setCurrentItem still works.

Voelker answered 9/3, 2017 at 5:30 Comment(1)
The canScrollHorizontally() method has no effect in current scenario. It is not even called when swipe happens.Dorri
D
1

This worked for me.

   ViewPager.OnPageChangeListener onPageChangeListener = new ViewPager.OnPageChangeListener() {
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            // disable swipe
            if(!swipeEnabled) {
                if (viewPager.getAdapter().getCount()>1) {
                    viewPager.setCurrentItem(1);
                    viewPager.setCurrentItem(0);
                }
            }
        }
        public void onPageScrollStateChanged(int state) {}
        public void onPageSelected(int position) {}
    };
    viewPager.addOnPageChangeListener(onPageChangeListener);
Ding answered 30/5, 2017 at 11:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.