android 觸控事件傳遞機制與筆記
一、筆記連結
1. android 觸控事件傳遞機制
2. android OnTouchListener,onTouchEvent,onClickListener執行順序
二、簡記
1. android 觸控事件傳遞機制
1.1Touch事件分發中只有兩個主角:ViewGroup和View。ViewGroup包含onInterceptTouchEvent、dispatchTouchEvent、onTouchEvent三個相關事件。View包含dispatchTouchEvent、onTouchEvent兩個相關事件。其中ViewGroup又繼承於View。
1.2.ViewGroup和View組成了一個樹狀結構,根節點為Activity內部包含的一個ViwGroup。
1.3.觸控事件由Action_Down、Action_Move、Aciton_UP組成,其中一次完整的觸控事件中,Down和Up都只有一個,Move有若干個,可以為0個。
1.4.當Acitivty接收到Touch事件時,將遍歷子View進行Down事件的分發。ViewGroup的遍歷可以看成是遞迴的。分發的目的是為了找到真正要處理本次完整觸控事件的View,這個View會在onTouchuEvent結果返回true。
1.5.當某個子View返回true時,會中止Down事件的分發,同時在ViewGroup中記錄該子View。接下去的Move和Up事件將由該子View直接進行處理。
要特別注意FrameLayout中子view的觸控事件傳遞:預設情況下(即不消費觸控事件),重疊的多個view都會接收到觸控事件/** * ViewGroup * @param ev * @return */ public boolean dispatchTouchEvent(MotionEvent ev){ ....//其他處理,在此不管 View[] views=getChildView(); for(int i=0;i<views.length;i++){ //判斷下Touch到螢幕上的點在該子View上面 if(...){ if(views[i].dispatchTouchEvent(ev)) return true; } } ...//其他處理,在此不管 } /** * View * @param ev * @return */ public boolean dispatchTouchEvent(MotionEvent ev){ ....//其他處理,在此不管 return false; }
FrameLayout 例項1(評論是重點), 例項2
2. android OnTouchListener,onTouchEvent,onClickListener執行順序
首先執行OnTouchListener,之後為onTouchEvent,最後才執行onClickListener內的方法
public boolean dispatchTouchEvent(MotionEvent event) { ...... 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; }
public boolean onTouchEvent(MotionEvent event) {
......
switch (action) {
case MotionEvent.ACTION_UP:
......
performClick();
......
break;
......
}
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;
}
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
return result;
}