標籤:code 方法 one intercept cli disable als false listen
簡介
事件也稱MotionEvent,事件分發機制就是對MotionEvent事件的分發過程,即當一個MotionEvent發生之後,系統需要把這個事件傳遞給一個具體的View。
點擊事件的分發過程由三個函數共同完成:
dispatchTouchEvent(DTE) - 進行事件的分發,如果時間能夠傳遞給當前View,該方法會被調用,返回結果受當前view的onTouchEvent, 子View的dispatchTouchEvent影響,表示是否消耗當前事件。onInterceptTouchEvent(OITE) - 是否攔截某個事件,如果當前View攔截了某個事件,那麼在同一個事件序列中,此方法不會被再次調用,返回結果表示是否攔截當前事件。onTouchEvent(OTE) - 在dispatchTouchEvent方法中調用,用來處理單擊事件,返回結果表示是否消耗當前事件,如果不消耗,則在同一時間序列中,當前View無法接收到事件。這三個函數的關係如下:
public boolean dispatchTouchEvent(MotionEvent ev){ boolean consume = false; if(onInterceptTouchEvent(ev)){ consume = onTouchEvent(); } else { consume = child.dispatchTouchEvent(ev); } return consume;}
點擊事件產生後,首先會發送給根Viewgroup,這是它的DTE會被調用。如果OITE返回true,表示要攔截當前事件,接著事件就會交給ViewGroup處理,即它的onTouchEvent方法就會被調用。如果OITE返回false,表示不攔截當前事件,當前事件會被傳遞給它的子項目,子項目的DTE會被調用。
當一個View需要處理事件時,如果它設定了onTouchListener(OTL),那麼OTL的onTouch方法會被回調。如果OnTouch返回false,當前View的onTouchEvent會被調用;如果返回true,那麼onTouchEvent不會被調用。給View設定的OTL會比onTouchEvent優先順序要高,在onTouchEvent中,如果當前設定有OnClickListener,那麼他的onClick方法會被調用。
當一個點擊事件產生後,它的傳遞過程遵循如下順序:Activity->Window->View, 如果View的onTouchEvent返回false,那麼它的父容器的onTouchEvent將會被調用,如果所有的元素都不處理這個事件,那麼事件將會被最終傳遞給Activity處理。
ViewGroup預設不攔截任何事件。OITE預設返回false。View沒有OITE方法,一旦有點擊事件傳遞給它,那麼他的onTouchEvent方法就會被調用。onTouchEvent預設都會消耗時間,除非它是不可點擊的。View的enable屬性不影響onTouchEvent預設傳回值,哪怕一個View是disable的狀態,只要它的clickable或者longClickable有一個是true,那麼它的onTouchEvent就會返回true。
Android中View的事件分發機制