1.事件分發(fā)核心方法
- dispatchTouchEvent (事件分發(fā),activity,ViewGroup,View 擁有)
- 返回true表示事件分發(fā)成功,事件消費(fèi)
- 返回false表示分發(fā)事件失敗,事件傳遞到上層View的onTouchEvent
- 默認(rèn)調(diào)用super.dispatchTouchEvent ,分發(fā)事件,執(zhí)行分發(fā)流程,
- onInterceptTouchEvent(事件攔截,ViewGroup擁有)
- 返回true,表示進(jìn)行攔截,不會(huì)進(jìn)行事件分發(fā)到子View,有viewgroup調(diào)用自己的onTouchEvent方法進(jìn)行處理。
- 返回false,不進(jìn)行攔截,執(zhí)行既定的分發(fā)過(guò)程
- ViewGroup默認(rèn)不攔截事件
- onTouchEvent(事件消耗,activity,ViewGroup,View 擁有)
- 執(zhí)行到該方法說(shuō)明該View/ViewGroup在觸摸返回內(nèi)
- 返回true,表示觸摸事件被該view消費(fèi)掉
- 返回false,表示觸摸事件該View沒(méi)有消費(fèi)掉,則依次回溯到上層傳遞的
2. 事件分發(fā)流程
- 分發(fā)流程:Activity======>ViewGroup(觸摸區(qū)域內(nèi))====>View(觸摸區(qū)域內(nèi))
- 消費(fèi)流程:View(onTouchEvent 返回false)======>ViewGroup(onTouchEvent 返回false)=====>Activity
2.1分發(fā)流程結(jié)論
- ACTION_DOWN 事件會(huì)一直分發(fā)到最底層的View并交由它的onTouchEvent方法處理,返回false,表示它不處理該事件序列,后續(xù)的move,up,等事件將不會(huì)向他分發(fā)。同理與這個(gè)事件序列的所有View,當(dāng)所有View都沒(méi)有消費(fèi)這個(gè)事件則最后調(diào)用activity的onTouchEvent方法,后續(xù)的move,up事件直接由activity的 dispatchTouchEvent (activity) ======>onTouchEvent(activ)
- 事件攔截onInterceptTouchEvent,可以攔截所有事件,也可以攔截部分事件,down-move-up,子View可以調(diào)用父View的requestDisallowInterceptTouchEvent,不允許父View攔截,但如果父View攔截了Down事件,這個(gè)方法是無(wú)效的。
- view什么時(shí)候會(huì)消耗事件,即onTouchEvent返回true,clickAble或longclickable有一個(gè)為真,具體表示就是添加相關(guān)的監(jiān)聽(tīng)事件,表示我們有相關(guān)業(yè)務(wù)需要處理。mOnTouchListener的ontouch事件要優(yōu)先于onTouchEvent事件,當(dāng)返回true時(shí),表示事件已經(jīng)被消費(fèi),不會(huì)再進(jìn)行分發(fā)。
view的dispatchTouchEvent 部分源碼
//noinspection SimplifiableIfStatement
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;
}
setOnTouchListener
/**
* Register a callback to be invoked when a touch event is sent to this view.
* @param l the touch listener to attach to this view
*/
public void setOnTouchListener(OnTouchListener l) {
getListenerInfo().mOnTouchListener = l;
}
setOnClickListener
/**
* Register a callback to be invoked when this view is clicked. If this view is not
* clickable, it becomes clickable.
*
* @param l The callback that will run
*
* @see #setClickable(boolean)
*/
public void setOnClickListener(@Nullable OnClickListener l) {
if (!isClickable()) {
setClickable(true);
}
getListenerInfo().mOnClickListener = l;
}
setOnLongClickListener
/**
* Register a callback to be invoked when this view is clicked and held. If this view is not
* long clickable, it becomes long clickable.
*
* @param l The callback that will run
*
* @see #setLongClickable(boolean)
*/
public void setOnLongClickListener(@Nullable OnLongClickListener l) {
if (!isLongClickable()) {
setLongClickable(true);
}
getListenerInfo().mOnLongClickListener = l;
}
3.事件序列
一個(gè)事件序列包含ACTION_DOWN(1次) -> ACTION_MOVE(N次) -> ACTION_UP(1次),事件分發(fā)包含一個(gè)完整的事件序列(從屏幕的的觸摸到離開(kāi)的過(guò)程)。

view事件分發(fā)規(guī)則說(shuō)明圖