點擊事件分發三個很核心的方法:dispatchTouchEvent(分發)、onInterceptTouchEvent(攔截)、onTouchEvent(處理)。
關於三者的關係可以用以下僞代碼表示:
pulic boolean dispatchTouchEvent(MotionEvent event){
boolean consume = false;
if (onInterceptTouchEvent(event)){
if (mOnTouchListener!=null && mOnTouchListener.onTouch(this, event)){
consume = true;
}
if (!consume){
consume = onTouchEvent(event);
}
} else {
consume = childView.dispatchTouchEvent(event);
}
return consume;
}
點擊事件產生首先傳遞給Activity,由activity的dispatchTouchEvent分發,在activity的 dispatchTouchEvent方法中把事件交給window,window是個抽象類,其實現類是PhoneWindow,而PhoneWindow把事件傳遞給DecorView(當前界面的底層容器,即setContentView所設置View的父容器),接着DecorView把事件傳遞給它的子View,就是setContentView設置的View,也是頂級View,這個View一般都是ViewGroup。
通過上述一系列傳遞到我們熟悉的ViewGroup後,觸發ViewGroup的dispatchTouchEvent事件,如果onInterceptTouchEvent返回true,表示自己攔截了,事件就會交給ViewGroup處理,反之事件向子元素傳遞,如果子元素也是一個ViewGroup,那麼跟上述流程一樣,如果子元素是View,因爲View沒有onInterceptTouchEvent方法,那麼它的onTouchEvent就會調用,另外我們可以看到上述僞代碼中有一個關於onTouch的判斷,因爲如果設置了OnTouchListener,那麼其中的onTouch就會被調用,可以在onTouch處理事件,如果onTouch返回true,那麼事件就被當前元素處理了,也不會調用onTouchEvent了,返回false則會調用,而且事件會向回傳遞給父類元素,之所以強調這個是因爲我們熟悉的onClickListener在onTouchEvent中調用,所以onClick事件的優先級是最低的。
以上參考《Android開發藝術探索》