Android的Touch事件處理機制

來源:互聯網
上載者:User

      Android的Touch事件處理機制比較複雜,特別是在考慮了多點觸摸以及事件攔截之後。

      Android的Touch事件處理分3個層面:Activity層,ViewGroup層,View層。

      首先說一下Touch事件處理的幾條基本規則。

      1.如果在某個層級沒有處理ACTION_DOWN事件,那麼該層就再也收不到後續的Touch事件了直到下一次ACTION_DOWN事件。

         說明:a.某個層級沒有處理某個事件指的是它以及它的子View都沒有處理該事件。

                 b.這條規則不適用於Activity層(它是頂層),它們可以收到每一個Touch事件。

                 c.如果沒有處理ACTION_MOVE這類事件,不會有任何影響。

      2.如果ACTION_DOWN事件發生在某個View的範圍之內,則後續的ACTION_MOVE,ACTION_UP和ACTION_CANCEL等事件都將被發往該View,即使事件已經出界了。

      3.第一根按下的手指觸發ACTION_DOWN事件,之後按下的手指觸發ACTION_POINTER_DOWN事件,中間起來的手指觸發ACTION_POINTER_UP事件,最後起來的手指觸發ACTION_UP事件(即使它不是觸發ACTION_DOWN事件的那根手指)。

      4.pointer id可以用於跟蹤手指,從按下的那個時刻起pointer id生效,直至起來的那一刻失效,這之間維持不變。

      5.如果一個ACTION_DOWN事件被父View攔截了,則任何子View不會再收到任何Touch事件了(這符合第1點的要求)。

      6.如果一個非ACTION_DOWN事件被父View攔截了,則那些上次處理了ACTION_DOWN事件的子View會收到一個ACTION_CANCEL事件,之後不會再收到任何Touch事件了,即使父View不再攔截後續的Touch事件。

      7.如果父View決定處理Touch事件或者子View沒有處理Touch事件,則父View按照普通View的處理方式處理Touch事件,否則它根本不處理Touch事件(它只負責分發)。

      8.如果父View在onInterceptTouchEvent中攔截了事件,則onInterceptTouchEvent中不會再收到Touch事件了,事件被直接交給它自己處理(按照普通View的處理方式)。

      下面分層講述一些細節。

      1.Activity層:

public boolean dispatchTouchEvent(MotionEvent ev) {        if (ev.getAction() == MotionEvent.ACTION_DOWN) {            onUserInteraction();        }        if (getWindow().superDispatchTouchEvent(ev)) { //在這裡交給View層處理            return true;        }        return onTouchEvent(ev); // 如果View層沒有處理,則在這裡處理}

      2.View層:

public boolean dispatchTouchEvent(MotionEvent event) {         // 省略了部分細節         ListenerInfo li = mListenerInfo;         if (li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED                    && li.mOnTouchListener.onTouch(this, event)) {             return true;         }         if (onTouchEvent(event)) {             return true;         }        return false;}

      View的onTouch方法代碼比較多,主要的邏輯分兩步:先是將事件交給TouchDelegate處理(如果有的話),如果TouchDelegate沒有處理再自行處理;自行處理主要負責View狀態的變換(如按下狀態),長按事件,點擊事件的檢測與觸發等。

      3.ViewGroup層(比較複雜):

      ViewGroup層處理Touch事件的總體邏輯是:先檢測是否需要攔截,沒有攔截的話下發給子View處理,如果子View沒有處理再自行處理,自行處理的邏輯與View一樣。

      攔截的邏輯是,將從down到up之間的所有事件看作一組事件,如果從down就攔截了,則組內的後續其它事件完全交給自己處理,不需要再進入攔截邏輯了;如果是從中間攔截,則先給子View發送cancel事件,組內的後續其它事件完全交給自己處理,不需要再進入攔截邏輯了。

      分發的邏輯是,在ACTION_DOWN事件的時候,尋找子View進行處理,稱為尋找Target;如果沒有找到Target,則自行處理;如果找到Target,則交由Target處理。

      從代碼上看,dispatchTouchEvent負責分發邏輯,onTouchEvent負責真正的處理邏輯,一般應該重載onTouchEvent,只有特殊情況下才需要重載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.