android - 如何禁止 ViewPager 向一个方向滑动

标签 android android-viewpager swipe

我想让用户只从右到左在 ViewPager 中滑动。因此,一旦他通过了一页,他就无法再回到它了。如何做到这一点?

我试过 this解决方案:

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);
    }
}
}

但它仍然让我无法向另一个方向滑动。

最佳答案

您还错过了一个事件:onInterceptTouchEvent。它必须包含与 onTouchEvent 相同的逻辑。

我的完整解决方案基于 this回答。它将允许您在任何需要的时候启用/禁用任何方向的分页。

1.创建枚举

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

2.Extend ViewPager(Java)

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;
    }
}

2.扩展 ViewPager(在 Kotlin 中)

enum class SwipeDirection {
    ALL, LEFT, RIGHT, NONE
}

class SingleDirectionViewPager @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet?
) : ViewPager(context, attrs) {

    private var initialXValue = 0f
    private var direction: SwipeDirection = SwipeDirection.ALL

    override fun onTouchEvent(event: MotionEvent): Boolean =
        if (isSwipeAllowed(event)) {
            super.onTouchEvent(event)
        } else {
            false
        }

    override fun onInterceptTouchEvent(event: MotionEvent): Boolean =
        if (isSwipeAllowed(event)) {
            super.onInterceptTouchEvent(event)
        } else {
            false
        }

    private fun isSwipeAllowed(event: MotionEvent): Boolean {
        if (direction == SwipeDirection.ALL) {
            return true
        }

        if (direction == SwipeDirection.NONE) {
            return false
        }

        if (event.action == MotionEvent.ACTION_DOWN) {
            initialXValue = event.x
            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
    }

    fun setAllowedSwipeDirection(direction: SwipeDirection) {
        this.direction = direction
    }
}

3.在布局中使用 viewPager

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

4.在代码中启用任意滑动方向。默认为全部(左右)

mViewPager.setAllowedSwipeDirection(SwipeDirection.RIGHT);

关于android - 如何禁止 ViewPager 向一个方向滑动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19602369/

相关文章:

android - 无法重置 SQLite 表中的主键编号

c# - 从某个日期 Android DatePicker 的几个月后禁用所有日期

android - 如何解决这个奇怪的 viewpager 问题?

iphone - 滑动手势有帮助吗?仅 LeftSwipe 有效,而 RightSwipe 无效

jquery - 使用 TouchSwipe 插件在滑动手势上调用其他 HTML 文件(超链接)

macos - 在 NSTableView OS X 中显示 rowActions

android - 带视频的 Cordova 插件相机媒体类型无法正常工作

java - ViewPager 不显示自定义 View

具有协调器布局的 ViewPager fragment 中的 Android 设计支持库 FAB

java - 如何在Android MapView中显示 map