Android Touch事件

來源:互聯網
上載者:User

  Android中跟Touch事件有關的事件有三個:
    public boolean dispatchTouchEvent(MotionEvent ev):傳遞Touch事件至target view(可以是自己)。
    public boolean onInterceptTouchEvent(MotionEvent ev):在ViewGroup中定義,用於攔截Touch事件的傳遞。
    public boolean onTouchEvent(MotionEvent event): Touch事件處理函數。

 

  先說下事件傳遞的兩種方式:
    隧道方式:從根項目依次往下傳遞直到最內層子項目或在中間某一元素中由於某一條件停止傳遞。 
    冒泡方式:從最內層子項目依次往外傳遞直到根項目或在中間某一元素中由於某一條件停止傳遞。

 

  Touch事件通過dispatchTouchEvent以隧道方式從上往下傳遞。如果在一個View中執行onTouchEvent時返回true的話,接下來的事件(ACTION_DOWN後的ACTION_UP,及可能在中間包含的若干個ACTION_MOVE,從ACTION_DOWN至ACTION_UP為一個連續事件,這是自己想的,不知道準確否)仍會傳遞到這個View的onTouchEvent,如果返回false的話,接下來的事件就不會再傳遞到這個View,而是執行其Parent View的onTouchEvent,每當一個View的onTouchEvent事件返回false,接下來的事件(如果還有的話)就會止步於這個View的Parent View,每次上升一個層次,類似於冒泡方式。

 

  Touch事件傳遞過程中經過的元素都是一個View,但是事件處理的最外層的元素卻不是View,除下跟Window有關的事件,當一個Touch事件發生的時候,會首先調用當前Activity的dispatchTouchEvent函數,然後才將事件傳遞至下層的View元素。當dispatchTouchEvent經過一個View往下傳遞的時候,如果這個View是一個ViewGroup,會調用其onInterceptTouchEvent函數,這個函數表示是否攔截Touch事件,如果這個函數返回true,表示這個ViewGroup攔截了事件的傳遞,Touch事件不會再往下傳遞給它的子View,而是由它處理,所以會調用它的onTouchEvent函數,如果在傳遞的過程中沒有ViewGroup攔截事件,即經過的所有ViewGroup都返回false,那麼事件最終會傳遞至最內層的View,一般是一個Widget,當然也可以是一ViewGroup(其內部不包含任何元素),如果最後事件傳遞到一View(非ViewGroup),那麼會首先調用這個View的onTouchListener(如果設定了的話),如果onTouchListener返回false則繼續調用View的onTouchEvent(預設返回true),如果最後事件傳遞到一ViewGroup(無子View),會調用它的onTouchEvent函數,預設返回false。

  如果調用一個View的onTouchEvent函數時返回true的話,那麼接下來的Touch Event事件(ACTION_DOWN後的ACTION_UP,及可能在中間包含的若干個ACTION_MOVE,從ACTION_DOWN至ACTION_UP為一個連續事件,這是自己想的,不知道準確否)仍會傳遞到這個View並調用它的onTouchEvent函數,在onTouchEvent函數中可以根據條件返回不同的值,如果某一次在此函數中返回了false那麼接下來的Touch Event事件就不會再傳遞到這個View,而會在其Parent View終止,調用其Parent View的onTouchEvent。如果所有的View都的onTouchEvent函數都返回false,那麼接下來的Touch Event事件會由Activity處理,即調用Activity的onTouchEvent函數。

 

  當調用ViewGroup的dispatchTouchEvent函數時,會首先調用onInterceptTouchEvent函數判斷有沒有攔截事件,如果沒有攔截(返回false),則會依次調用這個ViewGroup的所有子View的dispatchTouchEvent函數。比如一個FrameLayout上層疊了三個ViewGroup,那麼在這個FrameLayout的dispatchTouchEvent中會依次調用這三個ViewGroup的dispatchTouchEvent函數,而在這三個ViewGroup的dispatchTouchEvent中也會依次調用他們的子View的dispatchTouchEvent函數,直到其中一個View的dispatchTouchEvent返回true,表示已經處理了這個Touch事件,不需要再調用這個View的Slibling Views。比如調用這三個層疊的ViewGroup的dispatchTouchEvent函數時,如果第一個ViewGroup的dispatchTouchEvent函數就返回了true(已經消耗掉了這個事件),那麼其他兩個ViewGroup的dispatchTouchEvent就不會再被調用。可以自訂一個ViewGroup的子類並重載他的dispatchTouchEvent函數,使其處理過Touch事件後仍返回false,那麼就還會調用其他兄弟View的dispatchTouchEvent函數。

相關文章

聯繫我們

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