I want to disable the swiping, but only to the right side. I found a working solution in this answer. Unfortunately, this copies the whole ViewPager
source to achieve the goal. Is there any methods just inheriting the existing class and not duplicating?

- 1
- 1

- 11,947
- 13
- 63
- 105
-
Are you bound to use vanilla ViewPager? – Shark Sep 06 '13 at 14:24
-
If there is a lib which contains a `ViewPager` with this behavior, i can use it BTW. Note that i want to dynamically enable and disable right swiping, not just disable it statically. – WonderCsabo Sep 06 '13 at 14:27
-
I suppose you could try overriding onTouchEvent or onInterceptTouchEvent and try to filter out the touch events you don't want it to respond to (and call super for the rest). – Karakuri Sep 06 '13 at 14:27
-
Actually i have to copy everything because i want to modify a private method. :( – WonderCsabo Sep 06 '13 at 14:29
-
Preventing swipes is really easy, a single method call. Preventing them only to one side could prove a bit more difficult... – Shark Sep 06 '13 at 14:31
-
Create an object that extend ViewPager and do the custom work ;) – An-droid Sep 06 '13 at 14:31
7 Answers
I'm not sure this is exactly what you need: I needed a viewpager for a wizard with a max page that the user can't pass it.
At the end the solution was in the adapter. I changed the count of the PagerAdapter and this way blocks the user from passing the max page:
@Override
public int getCount() {
return mProgress; //max page + 1
}
When the user progresses to the next page:
private void setWizardProgress(int progress) {
if(progress > mProgress) {
mProgress = progress;
mWizardPagerAdapter.notifyDataSetChanged();
}
}
This way when the user is at max page he can't scroll to the right.

- 469
- 6
- 6
-
2Thanks! This is an old question, i already resolved this (via dropping `ViewPager` and using `Fragment` animations so i can completely control the flow). I think yours is a good solution, so i am accepting it. :) – WonderCsabo Feb 06 '14 at 13:46
-
1how did you do this can you share a snippet? how did you disable the swap on right side with this example. – badarshahzad Apr 17 '18 at 10:07
Here is working ViewPager class with possibility to disable any direction paging. Check out all the answer here .
public class CustomViewPager extends ViewPager {
private float initialXValue;
private SwipeDirection direction;
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
this.direction = SwipeDirection.all;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (this.IsSwipeAllowed(event)) {
return super.onTouchEvent(event);
}
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (this.IsSwipeAllowed(event)) {
return super.onInterceptTouchEvent(event);
}
return false;
}
private boolean IsSwipeAllowed(MotionEvent event) {
if(this.direction == SwipeDirection.all) return true;
if(direction == SwipeDirection.none )//disable any swipe
return false;
if(event.getAction()==MotionEvent.ACTION_DOWN) {
initialXValue = event.getX();
return true;
}
if(event.getAction()==MotionEvent.ACTION_MOVE) {
try {
float diffX = event.getX() - initialXValue;
if (diffX > 0 && direction == SwipeDirection.right ) {
// swipe from left to right detected
return false;
}else if (diffX < 0 && direction == SwipeDirection.left ) {
// swipe from right to left detected
return false;
}
} catch (Exception exception) {
exception.printStackTrace();
}
}
return true;
}
public void setAllowedSwipeDirection(SwipeDirection direction) {
this.direction = direction;
}

- 1
- 1

- 1,478
- 13
- 14
-
This thing actually works. (Though the syntax styling is very bad) – Vedant Agarwala Mar 02 '16 at 09:28
-
-
@lelloman probably means the lack of autoformat, IsSwipeAllowed with a big first letter, the try-catch where no exception is thrown and also the printStackTrace there, and "this" at unnecessary places (and the overriden methods could actually be inlined). But the answer is helpful anyway. – 0101100101 Apr 20 '17 at 23:15
-
Hi, @andre719mv This works fine with normal pages. But if pages contains EditText the touch is disabled so... This solution not work in that case. – Chinmay Sep 01 '17 at 06:58
-
-
-
2The try-catch block is unnecessary. Nothing inside it will throw an exception. – Egis Feb 25 '19 at 08:51
Another simple way is to use setCurrentItem() to scroll back to the desired slide if you hit a certain position. For instance, this will only allow forward swiping:
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
@Override
public void onPageSelected(int position) {
if(position < mProgress) {
mViewPager.setCurrentItem(mProgress, true);
} else {
mProgress = position;
}
}
@Override
public void onPageScrollStateChanged(int state) {}
});
Or if you want to have a max slide:
if(position > 4) {
mViewPager.setCurrentItem(4, true);
}
This solution will technically not completely disable the swipe, as you'll still see a small portion of the disallowed slide when you make your swipe movement. But for some applications this may be preferred.

- 849
- 4
- 31
- 66
You can try following:
Step 1: Create a new custom class say "CustomViewPager
". The class inherits from "ViewPager
" and includes a new customised method called "setPagingEnabled
" with a purpose to enable / disable the swiping, depending on the requirement.
Step2 : Override two methods: "onTouchEvent
" and "onInterceptTouchEvent
". Both will return "false
" if the paging is to be disabled completely.
Step 3: Substitute the "ViewPager
" tag on the layout file with customized class:
<package_name.customviewpager
android:id="@+id/customViewPager"
android:layout_height="match_parent"
android:layout_width="match_parent" />
Step 4: CustomViewPager.java
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 && detectSwipeToRight(event)) {
return super.onTouchEvent(event);
}
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (this.enabled && detectSwipeToRight(event)) {
return super.onInterceptTouchEvent(event);
}
return false;
}
// To enable/disable swipe
public void setPagingEnabled(boolean enabled) {
this.enabled = enabled;
}
// Detects the direction of swipe. Right or left.
// Returns true if swipe is in right direction
public boolean detectSwipeToRight(MotionEvent event){
int initialXValue = 0; // as we have to detect swipe to right
final int SWIPE_THRESHOLD = 100; // detect swipe
boolean result = false;
try {
float diffX = event.getX() - initialXValue;
if (Math.abs(diffX) > SWIPE_THRESHOLD ) {
if (diffX > 0) {
// swipe from left to right detected ie.SwipeRight
result = false;
} else {
// swipe from right to left detected ie.SwipeLeft
result = true;
}
}
}
catch (Exception exception) {
exception.printStackTrace();
}
return result;
}
}

- 16,629
- 6
- 44
- 72
-
5I tried the updated answer. `diffX` is always positive, so the method never returns `true`. – WonderCsabo Sep 06 '13 at 15:48
-
Hi wonderCsabo : did you get any soluton for the same ? i also tried lots of but still this type issue facing. Waiting for your replay. Thanks in advance. – Teraiya Mayur May 07 '15 at 06:18
-
This doesn't detect a swipe, it just detects if the first (and every subsequent) motion event X coordinate is greater than 0. This should always return false because X will always be positive. – Hamid May 15 '15 at 14:41
-
You can use the methods beginFakeDrag()
and endFakeDrag()
.
beginFakeDrag()
when you want disable the swipe
and endFakeDrag()
if you want enable again.
Like this: viewPager.beginFakeDrag();

- 5,476
- 2
- 35
- 57

- 71
- 4
private float initialXValue;
@Override
public boolean onTouchEvent(MotionEvent event) {
if (this.mEnabled) {
return super.onTouchEvent(event);
}
if(event.getAction()==MotionEvent.ACTION_DOWN){
initialXValue = event.getX();
}else if(event.getAction()==MotionEvent.ACTION_MOVE){
if(detectSwipeToRight(event)){
System.out.println("right swipe detected");
}
}
return true;
}
private boolean detectSwipeToRight(MotionEvent event) {
final int SWIPE_THRESHOLD = 100; // detect swipe
boolean result = false;
try {
float diffX = event.getX() - initialXValue;
if (Math.abs(diffX) > SWIPE_THRESHOLD) {
if (diffX < 0) {
// swipe from right to left detected ie.SwipeLeft
result = true;
}
}
} catch (Exception exception) {
exception.printStackTrace();
}
return result;
}

- 209
- 1
- 2
- 8
-
2This would be a much better answer if you explained the code a bit more. – skrrgwasme Apr 15 '15 at 18:10
You have to create your own ViewPager subclass and override the canScrollHorizontally function

- 5,519
- 1
- 18
- 25