先是ViewGroup 的dispatchTouchEvent,里面会执行onInterceptTouchEvent,会触发DOWN事件,如果不拦截,就继续往子View传,不走MOVE和UP,如果拦截就走MOVE和UP,消化掉事件,而且此处 如果在DOWN事件中 return true,子View都不会接收,但是 如果在MOVE中return true,而DOWN中是false,那子View的DOWN方法会执行,MOVE和UP都不会执行,而且此时,子View的CANCLE事件就会触发。
如果有某种变态的需求,就是如果ViewGroup的onInterceptTouchEvent(ev) 当ACTION_MOVE时return true ,即拦截了子View的MOVE以及UP事件;
此时子View希望依然能够响应MOVE和UP时,
那 就在子View中调用getParent().requestDisallowInterceptTouchEvent(true);
因为拦截的方法体中
if (!disallowIntercept && onInterceptTouchEvent(ev)) {
final float xc = scrolledXFloat - (float) target.mLeft;
final float yc = scrolledYFloat - (float) target.mTop;
mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT;
ev.setAction(MotionEvent.ACTION_CANCEL);
ev.setLocation(xc, yc);
if (!target.dispatchTouchEvent(ev)) {
// target didn't handle ACTION_CANCEL. not much we can do
// but they should have.
}
// clear the target
mMotionTarget = null;
// Don't dispatch this event to our own view, because we already
// saw it when intercepting; we just want to give the following
// event to the normal onTouchEvent().
return true;
}
判断的第一个条件 是 disallowIntercept ,所以直接跳过后面的
如果所有的View都不消化掉点击事件,那么
/**
* Called when a touch screen event was not handled by any of the views
* under it. This is most useful to process touch events that happen
* outside of your window bounds, where there is no view to receive it.
*
* @param event The touch screen event being processed.
*
* @return Return true if you have consumed the event, false if you haven't.
* The default implementation always returns false.
*/
public boolean onTouchEvent(MotionEvent event) {
if (mWindow.shouldCloseOnTouch(this, event)) {
finish();
return true;
}
return false;
}
就会执行activity的onTouch事件,而该Touch事件 一般是处理点击屏幕边缘的这种点击事件的,如果对这种事件有处理需求,那重写activity的onTouch方法即可。