1、本文的主要內容是對view的事件分發進行詳細的分析,view的相對于ViewGroup來說會簡單很多
1.1 在onTouchListener onTouch onClickListener 都有的情況下 在onTouchListener 返回為false 日志
09-11 08:01:47.864 6507-6507/? I/Tag: view -> onTouch ->0
09-11 08:01:47.864 6507-6507/? I/Tag: view -> onTouchEvent ->0
09-11 08:01:47.975 6507-6507/? I/Tag: view -> onTouch ->2
09-11 08:01:47.975 6507-6507/? I/Tag: view -> onTouchEvent ->2
09-11 08:01:48.088 6507-6507/? I/Tag: view -> onTouch ->1
09-11 08:01:48.088 6507-6507/? I/Tag: view -> onTouchEvent ->1
09-11 08:01:48.090 6507-6507/? I/Tag: view -> onClick
1.2 在onTouchListener onTouch onClickListener都有的情況在onTouchListener返回為true 日志
09-11 08:19:03.021 7029-7029/? I/Tag: view -> onTouch ->0
09-11 08:19:03.174 7029-7029/? I/Tag: view -> onTouch ->2
09-11 08:19:03.459 7029-7029/? I/Tag: view -> onTouch ->1
1.3 在onTouchListener onClickListener都有的情況在onTouchListener返回為true 日志
09-11 08:31:31.400 7620-7620/? I/Tag: view -> onTouch ->0
09-11 08:31:31.441 7620-7620/? I/Tag: view -> onTouch ->2
09-11 08:31:31.667 7620-7620/? I/Tag: view -> onTouch ->1
2、下面對源碼進行分析
2.1 找到view的源碼 dispatchTouchEvent(MotionEvent event) 這個方法 所有的view和ViewGroup的事件分發和響應都是從這里開始的可能不同的sdk版本源碼有些區別 我這里是7.1.1的
以下的有出現的代碼都是需要重點關注的 其他的可以不需要關注
boolean result = false 這句 這是dispatchTouchEvent返回值
ListenerInfo li = mListenerInfo;
這個ListenerInfo其實就是整個View中所有接口存放的位置
最重要的兩個方法之一
if (li != null && li.mOnTouchListener != null
&& (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) {
result = true;
}
這里li已經賦值了不可能等于空
mOnTouchListener 這個方法就是你是否實現了接口 這邊我們也不為空
(mViewFlags & ENABLED_MASK) == ENABLED 這個是你的view是否可用 也就是可不可以點擊
一般默認都是為可用 這里也是 true
li.mOnTouchListener.onTouch(this, event) 這個方法就是實現的方法
為什么onTouch是第一個調用也是這個原因 這里在1.1的情形中是返回false
所以 result = true;這個if判斷不會進來
if (!result && onTouchEvent(event)) {
result = true;
}
因為上面 if判斷沒進去 result 還是 false onTouchEvent(event)這里就調用了onTouchEvent 的方法
現在走到onTouchEvent內部看看 在這里面如果默認返回super.onTouchEvent(event) 這里都是返回true
在這個方法里會看到一個方法叫performClick() 這個就是點擊事件 我們進到里面看看
if (!post(mPerformClick)) {
performClick();
}
......
public boolean performClick() {
final boolean result;
final ListenerInfo li = mListenerInfo;
if (li != null && li.mOnClickListener != null) {
playSoundEffect(SoundEffectConstants.CLICK);
li.mOnClickListener.onClick(this);//這里就是onClick最后走的原因
result = true;
} else {
result = false;
}
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
return result;
}