源码分析
我们知道view的事件分发总是从dispatchTouchEvent方法开始,我们就来分析dispatchTouchEvent对应的源码执行逻辑:
public boolean dispatchTouchEvent(MotionEvent event) {
...
boolean result = false;
...
if (onFilterTouchEventForSecurity(event)) {
if ((mViewFlags & ENABLED_MASK) == ENABLED && handleScrollBarDragging(event)) {
result = true;
}
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;
}
重点分析这段代码:
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;
}
其中ListenerInfo:将View点击事件抽象成class,包含OnClickListener/OnFocusChangeListener/OnScrollChangeListener等等事件;
可以得出如下结论:
- 当View的
enable【view使能】为true时,会先执行OnTouchListener.onTouch事件,如果OnTouchListener.onTouch为true,则onTouchEvent事件不会执行,反之会执行onTouchEvent(event)事件
那OnClickListener事件在哪里执行的呢?我们看下onTouchEvent(event)方法这段源码:
switch (action) {
case MotionEvent.ACTION_UP:
...
if (!focusTaken) {
// Use a Runnable and post this rather than calling
// performClick directly. This lets other visual state
// of the view update before click actions start.
if (mPerformClick == null) {
mPerformClick = new PerformClick();
}
if (!post(mPerformClick)) {
performClickInternal();
}
}
}
...
break;
其中 performClickInternal()方法如下:
private boolean performClickInternal() {
notifyAutofillManagerOnClick();
return performClick();
}
performClick()方法如下:
public boolean performClick() {
...
final boolean result;
final ListenerInfo li = mListenerInfo;
if (li != null && li.mOnClickListener != null) {
playSoundEffect(SoundEffectConstants.CLICK);
li.mOnClickListener.onClick(this);
result = true;
} else {
result = false;
}
return result;
}
li.mOnClickListener.onClick(this)正是对应的OnClickListener事件回调。
这一段代码可以得出如下结论:
OnClickListener事件执行的前提是onTouchEvent(event)方法执行了MotionEvent.ACTION_UP事件。
总结
- 当
onTouchListener返回false时,执行顺序为onTouchListener->onTouchEvent->onClickListener; - 当
onTouchListener返回true时,只为执行onTouchListener; onClickListener执行的前提是执行了onTouchEvent且能执行MotionEvent.ACTION_UP事件。
该博客对Android中View的事件分发进行源码分析,将View点击事件抽象成class,包含多种事件。分析得出不同条件下事件的执行情况,如当View的某条件为true时事件执行逻辑,还总结了不同返回值时的执行顺序及前提条件。

1万+

被折叠的 条评论
为什么被折叠?



