Android觸控事件傳遞機制
摘要:
點選事件分發
ACTION_DOWN事件觸發時,會從Activity->PhoneWindow -> DecorView -> ViewGroup -> View順序,逐層呼叫對應的dispatchTouchEvent方法分發。
...
點選事件分發
- ACTION_DOWN事件觸發時,會從Activity->PhoneWindow -> DecorView -> ViewGroup -> View順序,逐層呼叫對應的dispatchTouchEvent方法分發。
- 在View的dispatchTouchEvent中,常理會呼叫onTouchEvent,在onTouchEvent方法中,ACTION_DOWN時,會檢查是否是長按,時長超過500毫秒則是長按;在ACTION_UP時,會呼叫performOnClickInteral,依次呼叫onClick(),響應點選事件。如果重寫onTouch()方法,返回true,則View的dispatchTouchEvent中,有一個if判斷條件成立,會將boolean區域性變數result置true,那麼接下來一個if判斷中,該result為true,就不會呼叫onTouchEvent方法,因此該次觸控事件則消費結束,不會再響應onLongClick和onClick。如果重寫onLongClick()方法,返回true,則在onTouchEvent方法中,ACTION_DOWN時,檢查是長按後,會呼叫onLongClick(),響應長按事件,該方法返回true後,會將mHasPerformedLongPress代表是否執行了長按事件的boolean值置true;在ACTION_UP時,呼叫performOnClickInteral前,會先判斷mHasPerformedLongPress,為true,則不調,為false,才呼叫。因此,重寫onLongClick()方法,返回true時,不會再響應onClick。
點選事件傳遞過程:
- ACTION_DOWN事件,Viewgroup的dispatchTouchEvent分發事件,onInterceptTouchEvent攔截事件,預設不攔截,繼續向下分發給子View,子View的dispatchTouchEvent分發事件,傳給子View的onTouchEvent,若返回true消費,則後面的ACTION_MOVE和ACTION_UP事件按順序繼續分發傳遞。
- 事件傳給子View的onTouchEvent時,子View返回false,不消費事件,則事件回傳給ViewGroup的onTouchEvent來消費,以後的時間會按照ViewGoup的dispatchTouchEvent到onTouchEvent來傳遞消費。
- 當ViewGroup的onInterceptTouchEvent攔截事件後,則會傳遞給ViewGroup的onToucnEvent消費,以後的其他事件也會按照ViewGoup的dispatchTouchEvent到onTouchEvent來傳遞消費,不會再傳給子View。
解決觸控事件衝突:
- 外部攔截。ViewGroup重寫onInterceptTouchEvent方法,預設不攔截,事件往下分發給子View,若返回true,則攔截此次事件,將事件傳給ViewGroup的onTouchEvent處理。
- 內部攔截。重寫子View的dispatchTouchEvent方法,方法中呼叫getParent().requestDisallowInterceptTouchEvent(true)方法,傳true則代表不希望ViewGroup攔截事件,傳false則代表希望ViewGroup攔截事件。
- 內部攔截。子View重寫onTouchEvent方法,返回true,則子View消費該次事件,返回false,該次事件返回給ViewGroup的onTouchEvent處理。