Android觸摸事件傳遞機制

點擊事件分發

  • 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。

點擊事件傳遞過程:

  1. ACTION_DOWN事件,Viewgroup的dispatchTouchEvent分發事件,onInterceptTouchEvent攔截事件,默認不攔截,繼續向下分發給子View,子View的dispatchTouchEvent分發事件,傳給子View的onTouchEvent,若返回true消費,則後面的ACTION_MOVE和ACTION_UP事件按順序繼續分發傳遞。
  2. 事件傳給子View的onTouchEvent時,子View返回false,不消費事件,則事件回傳給ViewGroup的onTouchEvent來消費,之後的時間會按照ViewGoup的dispatchTouchEvent到onTouchEvent來傳遞消費。
  3. 當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處理。
相關文章
相關標籤/搜索