Android事件分發

來源:互聯網
上載者:User

標籤:android事件   event   strong   com   src   --   一個   證明   one   

ViewGroup 分發-> 攔截 -> 處理  

在事件分發的過程中,主要涉及到三個方法:

  • dispatchTouchEvent(MotionEvent event);

  • onInterceptTouchEvent(MotionEvent event);

  • onTouchEvent();

分發處理流程:

1、在dispatchTouchEvent中,先調用ViewGroup自身的onInterceptTouchEvent方法,判斷自己是否要攔截。

2、如果這時候自己攔截,那就調用自己的onTouchEvent方法,如果onTouchEvent方法返回了True,那麼這次的事件就算消耗了,事件傳遞到此為止,,如果返回了False,證明這次沒有消耗這次MotionEvent,那麼這次的事件就會往上返回,由上一級繼續處理。

3、如果當前ViewGroup的onInterceptTouchEvent返回了False,那就會調用它的子view的dispatchTouchEvent方法,這樣這個事件就傳遞下去了,如果它的子View處理不了,那麼還會回來調用ViewGroup的onTouchEvent方法。

View

  View不同於ViewGroup的是,View中沒有onInterceptTouchEvent方法,因為View作為事件處理的最後一級,不需要判斷是否要攔截,是一定要攔截,不管能不能處理,都要試一下,所以在View中調用流程是:dispatchTouchEvent -> onTouchEvent

注意:

  view的enable狀態和onTouchEvent是沒有關係的,只有clickable狀態是對onTouchEvent有影響的。

  設定 view的enable為false確實也會把view的clickable設成false,但是設定view的onclickListener就又把view的clickable變成了true,所以最後的解決方案就是把那兩行代碼換下先後順序,問題就迎刃而解了。

GesutureDetector處理事件

  GestureDetector是一個手勢輔助檢測類,預設能夠檢測多種手勢:

onTouchListener OnTouchEvent OnClickListener

  我們在知道onTouchEvent之前肯定都知道onClickListener和onTouchListener,而他們都是事件的消費者,onTouchListener是在onTouch方法中生效,而且onTouch要先於onTouchEvent,就是說一旦設定了onTouchListener並且最後onTouch方法返回了True,那onTouchEvent將不會再被執行,而onClickListener和onTouchEvent有些關係,onTouchEvent的預設實現裡會調用onClickListener的onClick方法,如果重寫了onTouchEvent,因為onClickListener接受不到ACTION_DOWN和ACTION_UP,那麼再設定onClickListener也就不會再生效了,這個時候的單擊或者長按處理只能在onTouchEvent中自己處理。

 

結論:

1、如果事件不被攔截,整個事件傳遞流向將呈U型狀態。

  Activity---->ViewGroup--->View 從上往下調用dispatchTouchEvent方法,一直到葉子節點(View)的時候,再由View--->ViewGroup--->Activity從下往上調用onTouchEvent方法。

2、dispatchTouchEvent 和 onTouchEvent 一旦return true,事件就停止傳遞了(到達終點)

3、dispatchTouchEvent 和 onTouchEvent return false的時候事件都回傳給父控制項的onTouchEvent處理。

4、dispatchTouchEvent、onTouchEvent、onInterceptTouchEvent
  ViewGroup 和View的這些方法的預設實現就是會讓整個事件安裝U型完整走完,所以 return super.xxxxxx() 就會讓事件依照U型的方向的完整走完整個事件流動路徑),中間不做任何改動,不回溯、不終止,每個環節都走到。

總結:

  • 對於 dispatchTouchEvent,onTouchEvent,return true是終結事件傳遞。return false 是回溯到父View的onTouchEvent方法。
  • ViewGroup 想把自己分發給自己的onTouchEvent,需要攔截器onInterceptTouchEvent方法return true 把事件攔截下來。
  • ViewGroup 的攔截器onInterceptTouchEvent 預設是不攔截的,所以return super.onInterceptTouchEvent()=return false;
  • View 沒有攔截器,為了讓View可以把事件分發給自己的onTouchEvent,View的dispatchTouchEvent預設實現(super)就是把事件分發給自己的onTouchEvent。

  對於ACTION_MOVE、ACTION_UP總結:ACTION_DOWN事件在哪個控制項消費了(return true), 那麼ACTION_MOVE和ACTION_UP就會從上往下(通過dispatchTouchEvent)做事件分發往下傳,就只會傳到這個控制項,不會繼續往下傳,如果ACTION_DOWN事件是在dispatchTouchEvent消費,那麼事件到此為止停止傳遞,如果ACTION_DOWN事件是在onTouchEvent消費的,那麼會把ACTION_MOVE或ACTION_UP事件傳給該控制項的onTouchEvent處理並結束傳遞。

Android事件分發

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.