Android View 事件分发机制
// Activity.dispatchTouchEvent()
public boolean dispatchTouchEvent(MotionEvent ev) {
if (getWindow().superDispatchTouchEvent(ev)) {
return true;
}
return onTouchEvent(ev);
}
// PhoneWindow.superDispatchTouchEvent()
public boolean superDispatchTouchEvent(MotionEvent event) {
return mDecor.superDispatchTouchEvent(event);
}
// DecorView.superDispatchTouchEvent()
public boolean superDispatchTouchEvent(MotionEvent event) {
return super.dispatchTouchEvent(event);
}
// ViewGroup.dispatchTouchEvent()
public boolean dispatchTouchEvent(MotionEvent ev) {
if (actionMasked == MotionEvent.ACTION_DOWN) {
resetTouchState();// 重置FLAG_DISALLOW_INTERCEPT
}
/**
1、ViewGroup不拦截事件 -> mFirstTouchTarget != null
2、ViewGroup拦截事件 -> mFirstTouchTarget == null
3、ViewGroup拦截事件 -> ACTION_MOVE和ACTION_UP的onInterceptTouchEvent不执行
4、ACTION_DOWN -> onInterceptTouchEvent必执行
5、requestDisallowInterceptTouchEvent -> ViewGroup无法拦截非ACTION_DOWN事件
*/
if (actionMasked == MotionEvent.ACTION_DOWN || mFirstTouchTarget != null) {
disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
if (!disallowIntercept) {
intercepted = onInterceptTouchEvent(ev);
} else {
intercepted = false;
}
} else {
intercepted = true;
}
if (!intercepted) {
final View[] children = mChildren;
for (int i = childrenCount - 1; i >= 0; i--) {
View child = children[childIndex];
// 子元素是否在播动画 || 点击事件坐标是否在子元素区域内
if (!canViewReceivePointerEvents(child)
|| !isTransformedTouchPointInView(x, y, child)) {
continue;
}
newTouchTarget = getTouchTarget(child);
// -> child.dispatchTouchEvent
if (dispatchTransformedTouchEvent(ev, false, child)) {
// 设置mFirstTouchTarget
newTouchTarget = addTouchTarget(child);
break;
}
}
}
/**
1、ViewGroup没有子元素;
2、child.dispatchTouchEvent -> false : child.onTouchEvent -> false
*/
if (mFirstTouchTarget == null) {
// -> super.dispatchTouchEvent
handled = dispatchTransformedTouchEvent(ev, canceled, null);
}
return handled;
}
// View.dispatchTouchEvent()
public boolean dispatchTouchEvent(MotionEvent event) {
// mOnToucheListener.onTouch : true -> onTouchEvent不执行
if (mOnTouchListener != null && mOnTouchListener.onTouch(this, event)) {
result = true;
}
if (!result && onTouchEvent(event)) {
result = true;
}
return result;
}
// View.onTouchEvent()
public boolean onTouchEvent(MotionEvent event) {
// if(CLICKABLE || LONG_CLICKABLE) : onTouchEvent -> true
if ((viewFlags & ENABLED_MASK) == DISABLED) {
return (((viewFlags & CLICKABLE) == CLICKABLE
|| (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE));
}
if (((viewFlags & CLICKABLE) == CLICKABLE ||
(viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) {
switch (action) {
case MotionEvent.ACTION_UP:
performClick();// -> onClick()
break;
}
return true;
}
return false;
}
/**
1、ViewGroup -> dispatchTouchEvent 、onInterceptTouchEvent
2、View -> dispatchTouchEvent 、onTouchEvent
*/
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean consume = false;
if(onInterceptTouchEvent(ev)){
// super.dispatchTouchEvent -> View.dispatchTouchEvent -> onTouchEvent
consume = onTouchEvent(ev);
}else{
// View || ViewGroup -> dispatchTouchEvent
consume = child.dispatchTouchEvent(ev);
}
return consume;
}