How to disable ViewPager from swiping in one direction

Emil Adz picture Emil Adz · Oct 26, 2013 · Viewed 22.8k times · Source

I want to allow the user swipe in a ViewPager only from right to left. So once he passed a page he can't come back to it. How can this be done?

I tried this solution:

public class CustomViewPager extends ViewPager {

float lastX = 0;

boolean lockScroll = false;

public CustomViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public CustomViewPager(Context context) {
    super(context);
}

@Override
public boolean onTouchEvent(MotionEvent ev) {

    switch (ev.getAction()) {
    case MotionEvent.ACTION_DOWN:
        lastX = ev.getX();
        lockScroll = false;
        return super.onTouchEvent(ev);
    case MotionEvent.ACTION_MOVE:

        if (lastX > ev.getX()) {
            lockScroll = false;
        } else {
            lockScroll = true;
        }

        lastX = ev.getX();
        break;
    }

    lastX = ev.getX();

    if(lockScroll) {
        return false;
    } else {
        return super.onTouchEvent(ev);
    }
}
}

But it still allows me to poorly swipe in the other direction.

Answer

andre719mv picture andre719mv · Dec 3, 2015

There is one more event you miss: onInterceptTouchEvent. It`s must contain the same logic as onTouchEvent.

My complete solution is based on this answer. It will allow you to enable/disable paging in any direction in any time you need.

1. Create enum

 public enum SwipeDirection {
    ALL, LEFT, RIGHT, NONE ;
}

2.Extend ViewPager

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.action === MotionEvent.ACTION_MOVE) {
            val diffX = event.x - 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
            }
        }

        return true;
    }

    public void setAllowedSwipeDirection(SwipeDirection direction) {
        this.direction = direction;
    }
}

3.Use your viewPager in a layout

 <package_name.customviewpager 
     android:id="@+id/customViewPager" 
     android:layout_height="match_parent" 
     android:layout_width="match_parent" />

4.Enable any swipe direction in code. Default is all (right and left)

mViewPager.setAllowedSwipeDirection(SwipeDirection.RIGHT);