滑动冲突的处理规则滑动冲突的处理规则
一般来说,不管滑动冲突有多么复杂,它都有既定的规则,根据这些规则我们就可以选择合适的方法去处理。
对于场景1,它的处理规则就是:当用户左右滑动时,需要让外部的View拦截点击事件,当用户上下滑动,需要让内部View拦截点击事件。具体
来说就是根据滑动是水平滑动还是竖直滑动来判断到底是由谁来拦截事件。
如图:
简单来说,就是根据水平方向和竖直方向的距离差来判断,如果是Dx>Dy,那么则是水平滑动,如果是Dy>Dx,那么则是竖直滑动。
场景2,则是比较特殊,它无法根据滑动的角度,距离差以及速度差来做判断。这个时候就需要从业务上找到突破点,比如,当处于某种状态时
需要外部View响应用户的滑动,而处于另外一种状态时需要内部View来响应View的滑动
对于场景3的话,它的滑动规则也更复杂,和场景2一样,同样是从业务上找到突破点。
外部拦截法外部拦截法
外部拦截法是指点击事件都是先经过父容器的拦截处理,如果父容器需要此事件就拦截,如果不需要此事件,就不拦截了,这样就可以解决滑动
冲突的问题,外部拦截法需要重写父容器的onInterceptTouchEvent方法,在内部做相应的拦截即可,伪代码如下:
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
boolean intercepted = false;
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
intercepted = false;
break;
}
case MotionEvent.ACTION_MOVE: {
if (父容器需要点击当前事件) {
intercepted = true;
} else {
intercepted = false;
}
break;
}
case MotionEvent.ACTION_UP: {
intercepted = false;
break;
}
default:
break;
}
mLastXIntercept = x;
mLastYIntercept = y;
return intercepted;
}
首先ACTION_DOWN这个事件,父容器必须返回false,这样保证后续move和up的事件可以传递给子View,根据move事件来决定是否拦截,如
果父容器拦截就返回true,否则返回false。
实现一个自定义类似ViewPager的控件,嵌套ListView的效果,源代码如下: