android處理觸摸(touchEvent)詳細流程

來源:互聯網
上載者:User

使用者和應用程式的互動多數都是通過觸摸事件完成,所以有必要對事件處理的內部邏輯有瞭解,只有這樣,才能編寫事件時應用自如。下面開始吧

聲明:
      
   1.文中的WMS的全稱是:WIndowManagerServier
    2.文中所說的具體view,如果沒有特除說明,全部代表如TextView,BUtton等view,即非ViewGroup類

android對觸摸事件的處理邏輯簡單概述為:從上到下傳遞事件,然後從下到上處理時間邏輯,其實事實我們也可以理解,在你觸控螢幕幕的時候,首先第一層那道事件,然後一層一層傳下去,當傳到具體view,如TextView,BUtton等時,結束傳遞,然後開始處理。一層一層往上傳,但是在傳的過程中,會根據onTouchEvent及

onInterceptTouchEvent(MotionEvent ev)的傳回值,做不同操作吧了。下面會詳細分析返回不同值的處理邏輯

觸摸事件肯定由下面一系列動作 :

ACTION_DOWN->ACTION_MOVE->ACTION_MOVE->ACTION_MOVE...->ACTION_MOVE->ACTION_UP,肯定有一個down和up事件,按實際情況來講,也肯定從在move動作,因為人的手指在點的過程,肯定會從在一定情況的移動,只是感覺不到吧了,但是程式可以知道,只是程式理解了你的這個移動,不處理。

首先說一下事件的大概流程:事件接收層(底層:硬體和軟體,一般不需要瞭解)---->視窗管理系統 WindowMangerServicer (WMS)----->因為所有的視窗都是有他建立的,所有WMS知道當前活動的視窗是誰,WMS將事件交給當前使用中視窗-------->當前使用中視窗拿到事件,調用VIewRoot類的dispatchTouchEvent,給當前使用中視窗的根view--->根view開始dispatchTouchEvent事件到具體view。以下的討論是接著這裡開始詳細討論。

1.如果是具體view,(非ViewGroup),如TextView等 ,這種情況根本不存在,因為每個視窗,肯定有個rootview,及viewGroup。

2.如果是ViewGroup,比如LinearLayout等。

  • 如果是down事件,開始下面邏輯

  •     (--遞迴開始點-) 首先調用vieGroup的dispatchTouchEvent方法,如果是down事件,則清空上次處理該事件的對象(為了處理MOVE之類的事件,做的緩衝)mMotionTarget  = null;

  •     調用onInterceptTouchEvent方法,這個方法只有ViewGroup類有,具體view沒有,該方法的作用是判斷是否需要攔截該訊息,如果返回的是true,那麼訊息傳遞結束,調用該view對象的onTouchEvent方法。如果返回的是false,說明該view沒有消費事件,繼續往下走

  • 因為觸摸事件是視窗座標值,所以需要將座標值轉換為view自己的座標體系。

  • 轉換結束後,使用for迴圈遍曆,該view的所有子view,讀取子view的座標體系,即子view所佔的大小,是個Rect對象,上下左右,拿到這個值後,根據上面轉換好的座標,判斷點擊的座標是否包含在當前子view中,如果不包含,直接開始下一個子view

  • 如果座標包含在子view中,則調用子view的dispatchTouchEvent,如果子view還是ViewGroup類型的,那麼開始從上面標有(--遞迴開始點-)處遞迴調用。如果是具體view,則調用具體view的dispatchTouchEvent,這個方法比較簡單,首先判斷是否通過setTouchEventListener設定值,如果設定了,那麼調用onTouch方法,如果該方法返回的是ture,則直接返回,不在調用該view的OntouchEvent方法,如果返回false,則調用該view的OntouchEvent方法。並把該方法當作dispatchTouchEvent的返回者返回。

  • 具體view的dispatchTouchEvent處理結束後,子view的dispatchTouchEvent 如果返回的是true,該view的父view會將該view對象儲存到mMotionTarget,同時結束到本次down事件,如果放回的是false,則繼續for迴圈(個人此時可以推出for迴圈,因為感覺沒用,難道是擔心有view覆蓋的原因嗎),開始下一個子view

  • (--遞迴結束點-)for結束後(由於該過程是同步的,所以在執行這個過程中不會有其他的事件發送過來),判斷mMotionTarget是否為空白,如果為空白,說明沒有找到目標子view,所以調用當前view(一定是ViewGroup對象的,而且是迴圈體所在的view對象)的super.dispatchTouchEvent方法,這個是View基類的,實現和具體view的處理邏輯一樣,首先判斷是否通過setTouchEventListener設定值,如果設定了,那麼調用onTouch方法,如果該方法返回的是ture,則直接返回,不在調用該view的OntouchEvent方法,如果返回false,則調用該view的OntouchEvent方法。並把該方法當作
    dispatchTouchEvent的返回者返回 ,交給該ViewGroup的dispatchTouchEvent 的for迴圈(遞迴調用結束一個),這就說明,如果所有的子view不消費事件,那麼view會消費該事件,不管onInterceptTouchEvent的返回結果是ture還是false。同時結束本次事件。

  • 至此,一個Down事件就處理結束,處理結束後會通知WMS,此時WMS開始派發下一個事件。

  • 如果過來的事件是move或者up事件,首先判斷down處理邏輯得到mMotionTarget是否為空白,也就是說down處理中,是否找到的接收事件的子view。如果為空白:說明沒有找到目標子view,所以調用當前view(一定是ViewGroup對象的,而且是迴圈體所在的view對象)的super.dispatchTouchEvent方法,這個是View基類的,實現和具體view的處理邏輯一樣, 首先判斷是否通過setTouchEventListener設定值,如果設定了,那麼調用onTouch方法,如果該方法返回的是ture,則直接返回,不在調用該view的OntouchEvent方法,如果返回false,則調用該view的OntouchEvent方法。並把該方法當作
    dispatchTouchEvent的返回者返回 ,交給該ViewGroup的 dispatchTouchEvent 的for迴圈(遞迴調用結束一個),這就說明,如果所有的子view不消費事件,那麼view會消費該事件,不管onInterceptTouchEvent的返回結果是ture還是false。同時結束本次事件
  • 如果不為空白,這個時候mMotionTarget 的直接的直接父類只走dispatchTouchEvent事件,但是mMotionTarget 的爺爺及老爺還會走dispatchTouchEvent 和onInterceptTouchEvent事件,暫時沒弄明白,有明白的解釋一下,謝謝。那麼本次的move和up事件繼續由該子view處理,這樣的邏輯我們可以想到,因為同一個事件,應該有同一個view處理,而不是down事件是一個view處理,move和up事件是一個view處理。所以不為空白的情況下,直接由mMotionTarget的dispatchTouchEvent處理去。

  • 同時我們知道,在activity中還可以註冊ontouchEventListener,那麼他什麼時間執行了?他執行的時間就是在view中沒有找到消費該事件的view時,則交給acitivity去處理

到此,事件處理就分析結束,也該下班了,下周要開始幹活了,PM給任務了!!,以後有時間在學習源碼吧!!!!

總結:

  • 如果父view的onInterceptTouchEvent返回的是ture,那麼子view永遠拿不到touch事件,同時子view的onclick事件也不會處理,因為onclick事件是在view的ontouch事件中根據條件調用的,同時如果重新view的ontouchEvent方法,而沒有調用super.OntouchEvent.那麼onclick事件也不會處理
  • 如果給一個view設定了onTouchEventListener,同時設定了OnclickListener,而在onTouchListener的onTouch方法返回的是true,這個時候onClick事件不走,因為這個時候不調用onTouchEvent方法,而系統調用onclick事件在onTouchEvent中捕獲到up事件時,根據條件判斷執行的

http://www.eoeandroid.com/thread-200133-1-1.html

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.