Android View的事件分發機制筆記
阿新 • • 發佈:2019-01-24
- 涉及到的幾個概念:
同一個事件序列:手指接觸螢幕的那一刻起,到手指離開螢幕的那一刻結束。這個過程中產生的一系列事件,以down事件開始,中間可能包含多個move事件,最終以up事件結束。正常情況下,一個事件序列只能被一個view攔截且消耗,特殊情況下,這個view也可以將本該自己處理的事件通過onTouchEvent強行傳遞給子view處理。
- 事件傳遞規則
public boolean dispatchTouchEvent(MotionEvent ev)用於事件分發。返回結果表示是否消耗當前事件。
public boolean onInterceptTouchEvent(MotionEvent ev)
onTouchEvent(MotionEvent event)具體處理事件。返回結果表示是否消耗當前事件。如果不消耗,在同一個事件序列中,當前view無法再次接受到該事件。
上述3個方法關係虛擬碼如下(摘自《Android開發藝術探索》):
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean consume=false;
if(onInterceptTouchEvent(ev))
{
consume=onTouchEvent(ev);
}else {
consume= child.dispatchTouchEvent();//由下級view的dispatchTouchEvent()決定。
}
return consume;
}
注意:當一個view被設定了OnTouchListener,這時OnTouchListener中的onTouch方法會優先於這個View的onTouchEvent方法。當且僅當OnTouchListener中的onTouch返回false時View自己的onTouchEvent會被執行。
因此改進後的事件傳遞虛擬碼如下:
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean consume=disallowIntercept;//由子View設定給父View
if(!consume)
{
consume=onInterceptTouchEvent(ev);
}
if(consume)
{
if(mOnTouchListener!=null)
{
consume=mOnTouchListener.onTouch(this,ev);//優先執行
}
if(!consume)
{
consume=onTouchEvent(ev);
}
}else{
consume= child.dispatchTouchEvent();
}
return consume;
}
事件傳遞順序:Activity->Window->View