1、看下view的dispatchTouchEvent源码:
public boolean dispatchTouchEvent(MotionEvent event) {
//...
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnTouchListener != null
&& (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) {
result = true;
}
if (!result && onTouchEvent(event)) {
result = true;
}
}
//...
return result;
}
可以非常清楚看到,先执行的是onTouchListener的onTouch方法,如果返回true则代表事件被消费掉,则不会往下走到onTouchEvent中;
相反,如果没有消费则才往下走到onTouchEvent中。
2、接着看view的onTouchEvent方法:
可以很清楚看到,如果程序注册了onClickListener,则会执行onClickListener的onClick方法
总结如下:
1.view在执行dispatchTouchEvent的时候先要去判断该view是否有touchListener和执行TouchListener的onTouch方法的返回值。
2.TouchListener的onTouch方法返回false,事件继续传递在dispatch方法中调用了同级的onTouchEvent方法
3.然后在onTouchEvent方法中的UP事件中判断是否注册有onClickListener,有就执行onclick方法。
OnTouchListener --> onTouchEvent --> OnLongClickListener/OnClickListener
OnTouchListener是执行在onTouchEvent之前的,OnTouchListener优先级高于onTouchEvent,就是如果事件能传递到onTouchEvent中那么事件之前一定传递到了OnTouchListener中(当然如果像前面讲到的那种情况onTouchEvent中对ACTION_DOWN返回了false, 那后续的ACTION_UP等事件也就不会传到OnTouchListener和onTouchEvent中了)。如果在OnTouchListener的onTouch函数中返回了true,则代表消费了该事件,该事件也不会传到onTouchEvent中了。
而OnClickListener和OnLongClickListener都是在onTouchEvent中进行处理判断的,在onTouchEvent中返回true处理触摸事件才能判断该触摸事件是不是点击,如果在onTouchEvent返回false不处理触摸事件,则这时的OnClickListener和OnLongClickListener都是无效的。那OnClickListener和OnLongClickListener的区别就是OnLongClickListener在onTouchEvent判断到是ACTION_DOWN事件并且按压持续一定时间后就会触发OnLongClickListener;但之后要等到onTouchEvent判断到是ACTION_UP事件时才会触发OnClickListener,所以OnLongClickListener优先级要大于OnClickListener,当然如果在OnLongClickListener的onLongClick函数中返回true的话就不会触发后面的OnClickListener了。
事件分发实验:
android中的事件传递和处理机制 - fuly - 博客园
参考郭霖的事件分发机制解析:Android事件分发机制完全解析,带你从源码的角度彻底理解(上)_guolin的博客-CSDN博客_android事件分发流程
每日一问 | 事件到底是先到DecorView还是先到Window的?-玩Android - wanandroid.com
那天有人问我,Android 的事件到底是怎么来的?