View :
1、先执行disPatchTouchEvent方法,在这个方法中先判断 mTouchListener是否为空,如果不为空的话就调用mTouchListener.onTouch()方法。
2、如果 mTouchListener.onTouch()方法返回true,那么disPatchTouchEvent方法直接返回true,不在向下执行。
3、如果 mTouchListener.onTouch()方法返回返回false ,那么 result == false,继续调用 onTouchEvent(),这样onTouchEvent就被执行了。
4、在onTouchEvent()中判断 onClickListener是否存在,如果存在就调用onClickListener的onClick(),这样我们注册进来的onClickListener就被执行了。
在view的onTouchEvent中click和longclick执行完成后返回了true(默认就返回true),同时把true返回给disPatchTouchEvent,事件消费掉了。
通过View的源码加以说明:
//源码分析:
public boolean dispatchTouchEvent(MotionEvent event) {
...
...
//noinspection SimplifiableIfStatement
ListenerInfo li = mListenerInfo; // 这里面集合了所有注册过来的listener,包括clickListener,touchListener
if (li != null && li.mOnTouchListener != null // listener不为空
&& (mViewFlags & ENABLED_MASK) == ENABLED // view是可点击的状态
&& li.mOnTouchListener.onTouch(this, event)) { // 执行TouchListener.onTouch方法,并根据返回值进行判断
result = true;
}
//
if (!result && onTouchEvent(event)) { // 调用onTouchEvent,里面再执行onClick/onLongClick
result = true;
}
reutrn result;
}
ViewGroup:
主要是三个方法:
dispatchTouchEvent(MotionEvent event) // 这个方法一定会调用,同时返回结果受当前View的onTouchEvent和子View的disPatchTouchEvent影响。
onInterceptTouchEvent(MotionEvent event) // 这个方法在ViewGroup的dispatchTouchEvent()方法中调用,用于判断当前布局是否拦截点击事件,需要拦截之后直接调用onTouchEvent()
onTouchEvent(MotionEvent event) // 在dispatchTouchEvent()方法中调用。如果这个方法在接收到action_down后返回的是false,那么说明他不处理,需要向上传递,由上层处理。上层的onTouchEvent接收到以后重复这样的判断。只有处理了action_down事件的那个view才会接收到down之后的move和up事件。
public boolean dispatchTouchEvent(MotionEvent event) {
...
...
// 先判断是否需要拦截
if(onInterceptTouchEvent(event)){
// 需要拦截就直接处理
onTouchEvent(event)
}else{
// 不拦截就再向下(子view)传递
child.disPatchTouchEvent(event); // 这个传递过程符合view的事件处理过程
}
reutrn result;
}
注 :详细的传递过程看这里