相关方法介绍:
dispatchTouchEvent方法:事件的分发。返回值一般由里面的onTouchEvent方法或者下架View的dispatchTouchEvent方法决定。
onInterceptTouchEvent:事件的拦截,如果Down事件一旦拦截了,那么之后的move和up事件也会一起拦截。事件不会在向下传递。
onTouchEvent:事件的处理。如果在子View中设定了mOnTouchListener,那么会优先调用mOnTouchListener的方法。如果返回true,
那么不会在调用onTouchEvent。如果返回false,那么会继续走onTouchEvent。如果一个View的down事件没有
消耗,直接返回的false,那么其他事件都不会在传递到这个View上。事件开始向上传递。
事件传递源头:Activity的dispatchTouchEvent方法。
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
onUserInteraction();
}
if (getWindow().superDispatchTouchEvent(ev)) {
return true;
}
return onTouchEvent(ev);
}
由源码可以知道,触摸事件由getWindow().superDispatchTouchEvent(ev)传递下去,如果下面的UI控件没有消耗该时间
由activity的onToucHEvent去消耗。getWindow().superDispatchTouchEvent(ev)的具体实现如下:
@Override
public boolean superDispatchTouchEvent(MotionEvent event) {
return mDecor.superDispatchTouchEvent(event);
}
由代码可知,事件由整个窗口布局的根View DecorView负责进行分发。
public boolean superDispatchTouchEvent(MotionEvent event) {
return super.dispatchTouchEvent(event);
}
在 DecorView中,直接调用了super.dispatchTouchEvent(event),而DecorView是一个FrameLayout,即该方法
走入了ViewGroup里面的dispatchTouchEvent。接下来具体分析该方法
第一段: // Handle an initial down.
if (actionMasked == MotionEvent.ACTION_DOWN) {
// Throw away all previous state when starting a new touch gesture.
// The framework may have dropped the up or cancel event for the previous gesture
// due to an app switch, ANR, or some other state change.
cancelAndClearTouchTargets(ev);
resetTouchState();
}
如果事件是DOWN事件,那么初始化一些状态。
第二段:
final boolean intercepted;
if (actionMasked == MotionEvent.ACTION_DOWN
|| mFirstTouchTarget != null) {