View学习之解决滑动冲突

 

 

一、常见的滑动冲突场景

  1.外部滑动方向和内部滑动的方向不一致

  View学习之解决滑动冲突

        图一

  2.外部滑动方向和内部滑动方向一致

  View学习之解决滑动冲突

             图二

 

二、解决方法

  1.外部拦截法 : 外部和内部的滑动方向不一样也就是说只要判断当前dy和dx的大小,如果dy>dx,那么当前就是竖直滑动,否则就是水平滑动

View学习之解决滑动冲突

父view:

public boolean onInterceptTouchEvent(MotionEvent ev) {
final float x = ev.getX();
final float y = ev.getY();

final int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
mDownPosX = x;
mDownPosY = y;

break;
case MotionEvent.ACTION_MOVE:
final float deltaX = Math.abs(x - mDownPosX);
final float deltaY = Math.abs(y - mDownPosY);
// 这里是够拦截的判断依据是左右滑动,读者可根据自己的逻辑进行是否拦截
if (deltaX > deltaY) {
return false;
}
}

return super.onInterceptTouchEvent(ev);
}

  


  2.内部拦截法 : 指父容器不拦截任何事件,所有的事件都传递给子元素,如果子元素需要此事件就直接消耗掉,否则就交给父容器去处理,这种方法和Android中的事件分发机制不一致,
          需要配合requestDisallowInterceptTouchEvent方法才能正常工作
子view :

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
int x = (int) ev.getRawX();
int y = (int) ev.getRawY();
int dealtX = 0;
int dealtY = 0;

switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
dealtX = 0;
dealtY = 0;
// 保证父view不做拦截
getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_MOVE:
dealtX += Math.abs(x - lastX);
dealtY += Math.abs(y - lastY);
Log.i(TAG, "dealtX:=" + dealtX);
Log.i(TAG, "dealtY:=" + dealtY);
// 这里是够拦截的判断依据是左右滑动,读者可根据自己的逻辑进行是否拦截
if (dealtX >= dealtY) {
getParent().requestDisallowInterceptTouchEvent(true);
} else {
        //保证父view做拦截
getParent().requestDisallowInterceptTouchEvent(false);
}
lastX = x;
lastY = y;
break;
case MotionEvent.ACTION_CANCEL:
break;
case MotionEvent.ACTION_UP:
break;

}
return super.dispatchTouchEvent(ev);
}

 

上一篇:js-事件1_事件对象event/ev 兼容性及其简易写法


下一篇:tools:context=".MainActivity的作用 (转载)