一,写在前面
本篇文章是接着Android事件分发机制之源码解析(ViewGroup篇) 来写的,主要介绍View$dispatchTouchEvent(ev),在ViewGroup篇很详细介绍了事件从Activity开始传递的过程,看这篇文章的哥们,一定是需要看ViewGroup篇的,否则可能对本篇分析View$dispatchTouchEvent(ev)的原因也不太清楚。
我们知道不管是容器控件ViewGroup,还是原始的View(非容器控件),最终对事件的处理是放在它们的基类--View,由View的dispatchTouchEvent(ev)处理。具体的原因,见Android事件分发机制之源码解析(ViewGroup篇) 。
二,源码分析
查看View$dispatchTouchEvent(ev)源码:
public boolean dispatchTouchEvent(MotionEvent event) {
if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onTouchEvent(event, 0);
}
if (onFilterTouchEventForSecurity(event)) {
//noinspection SimplifiableIfStatement
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) {
return true;
}
if (onTouchEvent(event)) {
return true;
}
}
if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
}
return false;
}
参数MotionEvent:对触摸的位置,时间等的封装。我们说事件的分发,在代码角度,是由MotionEvent对象在方法间的传递体现。
首先看第9行,第10行的代码:li != null是一个判空操作,不用管;
li.mOnTouchListener != null,在我们调用view.setOnTouchListener(OnTouchListener listener)且listener不为空时,其为true;
li.mOnTouchListener.onTouch(this, event),是一个接口的回调,当onTouch方法返回true时,其为true;
(mViewFlags & ENABLED_MASK) == ENABLED,如果该View是可用的,其为true。可以调用view.setEnabled(boolean)改变view是否可用,view.isEnabled()查看值。
也就是说只要View是可用的,且调用setOnTouchListener方法,且onTouch(...)方法返回true,那么View$dispatchTouchEvent返回true,事件就被消费掉了。