Android的View 事件傳遞

來源:互聯網
上載者:User

標籤:返回   .net   gen   事件   viewgroup   時間   事件傳遞   demo   總結   

歡迎轉載,請附出處:
http://blog.csdn.net/as02446418/article/details/47422891

1、基礎知識

(1) 全部 Touch 事件都被封裝成了 MotionEvent 對象,包含 Touch 的位置、時間、記錄以及第幾個手指(多指觸摸)等。

(2) 事件類型分為 ACTION_DOWN, ACTION_UP, ACTION_MOVE, ACTION_POINTER_DOWN, ACTION_POINTER_UP, ACTION_CANCEL,每一個事件都是以 ACTION_DOWN 開始 ACTION_UP 結束。

(3) 對事件的處理包含三類,分別為傳遞——dispatchTouchEvent()函數、攔截——onInterceptTouchEvent()函數、消費——onTouchEvent()函數和 OnTouchListener

2、傳遞流程

(1) 事件從 Activity.dispatchTouchEvent()開始傳遞。僅僅要沒有被停止或攔截,從最上層的 View(ViewGroup)開始一直往下(子 View)傳遞。子 View 能夠通過 onTouchEvent()對事件進行處理。

(2) 事件由父 View(ViewGroup)傳遞給子 View,ViewGroup 能夠通過 onInterceptTouchEvent()對事件做攔截,停止其往下傳遞。

(3) 假設事件從上往下傳遞過程中一直沒有被停止,且最底層子 View 沒有消費事件,事件會反嚮往上傳遞,這時父 View(ViewGroup)能夠進行消費,假設還是沒有被消費的話。最後會到 Activity 的 onTouchEvent()函數。

(4) 假設 View 沒有對 ACTION_DOWN 進行消費,之後的其它事件不會傳遞過來。

(5) OnTouchListener 優先於 onTouchEvent()對事件進行消費。
上面的消費即表示對應函數傳回值為 true。

很多其它請直接閱讀 PDF 英文原文:Mastering the Android Touch System

示範範例代碼:[email protected]

附上兩張原文中流程圖:
(1) View 不處理事件流程圖


(2) View 處理事件流程圖

3、最後說幾句

Android Touch事件
假設布局層次為
Layout0
Layout1
Layout2
Layout3

假設誰都沒有去interceptTouch,同一時候誰都沒有處理onTouch事件。


那麼Layout0->intercept Layout1->intercept Layout2->intercept Layout3->intercept
Layout3->onTouch Layout2->onTouch Layout1->onTouch Layout0->onTouch
因為誰都沒有消費ACTION_DOWN事件,興許的MOVE,UP事件將不會傳進來。

假設Layout2 intercept了,可是不消費onTouch
那麼Layout0->intercept Layout1->intercept Layout2->intercept
Layout2->onTouch Layout1->onTouch Layout0->onTouch
興許事件不會傳入

假設Layout2 intercept了,同一時候消費了。
那麼 0->intercept 1->intercept 2->intercept 2->onTouch
0->intercept 1->intercept 2->onTouch
0->intercept 1->intercept 2->onTouch
0->intercept 1->intercept 2->onTouch

假設Layout2 intercept了。不消費,Layout1消費了。
那麼0->intercept 1->intercept 2->intercept
2->onTouch 1->onTouch
0->intercept 1->onTouch
0->intercept 1->onTouch
0->intercept 1->onTouch

總結一下。

規律就是
假設當前Layout intercept了,那麼子View和子ViewGroup都沒有機會去獲得Touch事件了。

假設當前Layout並不消費事件的話,這個事件會一直向上冒泡,直到某個父Layout的onTouchEvent消費了這個事件。

假設沒有不論什麼一個父Layout消費這個事件,那麼興許的事件都不會被接受。
假設在冒泡過程中有某個Layout消費了這個事件。那麼這個Layout的全部父Layout的intercept仍然會被調用。可是當前Layout的intercept不會再被調用了。

直接調用onTouch事件。

另外,對於底層的View來說,有一種方法能夠阻止父層的View截獲touch事件,就是調用getParent().requestDisallowInterceptTouchEvent(true);方法。一旦底層View收到touch的action後調用這種方法那麼父層View就不會再調用onInterceptTouchEvent了,也無法截獲以後的action。在實踐過程中發現ListView在滾動的時候會調用這種方法。

使得action不能被攔截。

Android的View 事件傳遞

相關文章

聯繫我們

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