读任玉刚大神出版书籍《Android开发艺术探索》笔记。
1.外部拦截法
所有的事件先经过父容器的拦截处理,如果需要则处理。
1.重写父容器的onInterceptTouchEvent方法。
-
默认不拦截ACTION_DOWN事件,否则子元素将收不到事件。
-
ACTION_MOVE按需拦截。
-
ACTION_UP不能拦截,否则子元素无法响应点击事件。
private int mLastXIntercept;
private int mLastYIntercept;
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean intercepted = false;
int x = (int) ev.getX();
int y = (int) ev.getY();
switch (ev.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;
}
mLastXIntercept = x;
mLastYIntercept = y;
return intercepted;
}
2.内部拦截法
父容器不拦截ACTION_DOWN事件。子元素如果需要处理,消耗掉事件;否则交由父容器处理。
1、重写子元素的dispatchTouchEvent方法。
-
ACTION_DOWN中告诉父元素不要拦截,否则子元素将无法收到任何事件。
-
ACTION_MOVE中按需通知父元素。
2、重写父容器的onInterceptTouchEvent方法。
-
不拦截ACTION——DOWN事件,否则子元素将无法收到任何事件。
-
拦截其他事件。
//-------------------------父容器-------------------------
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return ev.getAction() != MotionEvent.ACTION_DOWN;
}
//-------------------------子元素-------------------------
private int mLastX;
private int mLastY;
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
int x = (int) ev.getX();
int y = (int) ev.getY();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_MOVE:
if (父容器需要处理) {
getParent().requestDisallowInterceptTouchEvent(false);
} else {
子元素逻辑处理
}
break;
case MotionEvent.ACTION_UP:
break;
default:
break;
}
mLastX = x;
mLastY = y;
return super.dispatchTouchEvent(ev);
}
网友评论