你错过的还有一个事件:onInterceptTouchEvent。它必须包含与onTouchEvent相同的逻辑。
我的完整解决方案基于这个答案。它将允许您在任何时候启用/禁用任何方向上的分页。
1. 创建枚举
public enum SwipeDirection {
ALL, LEFT, RIGHT, NONE ;
}
2.扩展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 )
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) {
return false
} else if (diffX < 0 && direction === SwipeDirection.LEFT) {
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) {
return false
} else if (diffX < 0 && direction === SwipeDirection.LEFT) {
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)
ViewPager.canScroll
方法并在应禁用滚动时返回true
来解决了问题。你可以在这里找到解决方案 - http://pastebin.com/sCcFu0Yn。它有一些问题,有时仍然允许滚动,但对我来说完全合适。如果有帮助,请告诉我,我会发布答案。 - Vladimir Mironov