android onTouchEvent和onInterceptTouchEvent區別

來源:互聯網
上載者:User

最近師兄讓我分析下onTouchEvent和onInterceptTouchEvent的區別,在網上尋找了很多資料,但發現自己測試的結果和他們說的有不一樣的地方,當所有的onTouchEvent和onInterceptTouchEvent返回的都是false時,只有DOWN事件會按他們說的流程執行,而MOVE和UP事件則不會被響應。

 

測試1:

LayoutView1.onInterceptTouchEvent返回false.

 

LayoutView1.onTouchEvent返回false.

 

LayoutView2.onInterceptTouchEvent返回false.

 

LayoutView2.onTouchEvent返回false.

 

MyTextView.onTouchEvent返回false.

 

測試1結果:

05-16 01:54:37.742: INFO/System.out(894): LayoutView1.onInterceptTouchEvent.DOWN


05-16 01:54:37.742: INFO/System.out(894): LayoutView2.onInterceptTouchEvent.DOWN


05-16 01:54:37.742: INFO/System.out(894): MyTextView.onTouchEvent.DOWN


05-16 01:54:37.752: INFO/System.out(894): LayoutView2.onTouchEvent.DOWN


05-16 01:54:37.752: INFO/System.out(894): LayoutView1.onTouchEvent.DOWN


測試2:LayoutView1.onInterceptTouchEvent返回false.

 

LayoutView1.onTouchEvent返回false.

 

LayoutView2.onInterceptTouchEvent返回true.

 

LayoutView2.onTouchEvent返回false.

 

MyTextView.onTouchEvent返回false.

 

測試2結果:

 

05-16 01:58:17.602: INFO/System.out(923): LayoutView1.onInterceptTouchEvent.DOWN

 

05-16 01:58:17.622: INFO/System.out(923): LayoutView2.onInterceptTouchEvent.DOWN

 

05-16 01:58:17.622: INFO/System.out(923): LayoutView2.onTouchEvent.DOWN

 

05-16 01:58:17.622: INFO/System.out(923): LayoutView1.onTouchEvent.DOWN

 

經過以上測試,我認為應該在下邊轉載的文章中添加一條:

如果沒有任何視圖的onTouchEvent返回true,則UP和MOVE事件將不會被任何試圖的onInterceptTouchEvent和onTouchEvent捕捉。

轉自:http://www.javaask.com/mobile/android/2011/0419/6890.html

 

onInterceptTouchEvent和onTouchEvent調用時序
onInterceptTouchEvent()是ViewGroup的一個方法,目的是在系統向該ViewGroup及其各個childView觸發onTouchEvent()之前對相關事件進行一次攔截,Android這麼設計的想法也很好理解,由於ViewGroup會包含若干childView,因此需要能夠統一監控各種touch事件的機會,因此純粹的不能包含子view的控制項是沒有這個方法的,如LinearLayout就有,TextView就沒有。 
onInterceptTouchEvent()使用也很簡單,如果在ViewGroup裡覆寫了該方法,那麼就可以對各種touch事件加以攔截。但是如何攔截,是否所有的touch事件都需要攔截則是比較複雜的,touch事件在onInterceptTouchEvent()和onTouchEvent以及各個childView間的傳遞機制完全取決於onInterceptTouchEvent()和onTouchEvent()的傳回值。並且,針對down事件處理的傳回值直接影響到後續move和up事件的接收和傳遞。 
關於傳回值的問題,基本規則很清楚,如果return true,那麼表示該方法消費了此次事件,如果return false,那麼表示該方法並未處理完全,該事件仍然需要以某種方式傳遞下去繼續等待處理。

由於onInterceptTouchEvent()的機制比較複雜,上面的說明寫的也比較複雜,總結一下,基本的規則是:
1.       down事件首先會傳遞到onInterceptTouchEvent()方法
2.       如果該ViewGroup的onInterceptTouchEvent()在接收到down事件處理完成之後return false,那麼後續的move, up等事件將繼續會先傳遞給該ViewGroup,之後才和down事件一樣傳遞給最終的目標view的onTouchEvent()處理。
3.       如果該ViewGroup的onInterceptTouchEvent()在接收到down事件處理完成之後return true,那麼後續的move, up等事件將不再傳遞給onInterceptTouchEvent(),而是和down事件一樣傳遞給該ViewGroup的onTouchEvent()處理,注意,目標view將接收不到任何事件。
4.       如果最終需要處理事件的view的onTouchEvent()返回了false,那麼該事件將被傳遞至其上一層次的view的onTouchEvent()處理。
5.       如果最終需要處理事件的view 的onTouchEvent()返回了true,那麼後續事件將可以繼續傳遞給該view的onTouchEvent()處理。

下面用一個簡單的實驗說明上述複雜的規則。視圖自底向上共3層,其中LayoutView1和LayoutView2就是LinearLayout, MyTextView就是TextView:
對應的xml布局檔案如下:
<?xml version="1.0" encoding="utf-8"?>
<com.touchstudy.LayoutView1 xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <com.touchstudy.LayoutView2
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="center">
       <com.touchstudy.MyTextView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/tv"
            android:text="AB"
            android:textSize="40sp"
            android:textStyle="bold"
            android:background="#FFFFFF"
            android:textColor="#0000FF"/>
   </com.touchstudy.LayoutView2>
</com.touchstudy.LayoutView1>

下面看具體情況:
1.       onInterceptTouchEvent()處理down事件均返回false,onTouchEvent()處理事件均返回true
------------------------------------------------------------------------------------------------------------------------------
04-11 03:58:42.620: DEBUG/LayoutView1(614): onInterceptTouchEvent action:ACTION_DOWN
04-11 03:58:42.620: DEBUG/LayoutView2(614): onInterceptTouchEvent action:ACTION_DOWN
04-11 03:58:42.620: DEBUG/MyTextView(614): onTouchEvent action:ACTION_DOWN
04-11 03:58:42.800: DEBUG/LayoutView1(614): onInterceptTouchEvent action:ACTION_MOVE
04-11 03:58:42.800: DEBUG/LayoutView2(614): onInterceptTouchEvent action:ACTION_MOVE
04-11 03:58:42.800: DEBUG/MyTextView(614): onTouchEvent action:ACTION_MOVE
…… //省略過多的ACTION_MOVE
04-11 03:58:43.130: DEBUG/LayoutView1(614): onInterceptTouchEvent action:ACTION_UP
04-11 03:58:43.130: DEBUG/LayoutView2(614): onInterceptTouchEvent action:ACTION_UP
04-11 03:58:43.150: DEBUG/MyTextView(614): onTouchEvent action:ACTION_UP
------------------------------------------------------------------------------------------------------------------------------
這是最常見的情況,onInterceptTouchEvent並沒有做任何改變事件傳遞時序的操作,效果上和沒有覆寫該方法是一樣的。可以看到,各種事件的傳遞本身是自底向上的,次序是:LayoutView1->LayoutView2->MyTextView。注意,在onInterceptTouchEvent均返回false時,LayoutView1和LayoutView2的onTouchEvent並不會收到事件,而是最終傳遞給了MyTextView。

2.       LayoutView1的onInterceptTouchEvent()處理down事件返回true,
MyTextView的onTouchEvent()處理事件返回true
------------------------------------------------------------------------------------------------------------------------------
04-11 03:09:27.589: DEBUG/LayoutView1(446): onInterceptTouchEvent action:ACTION_DOWN
04-11 03:09:27.589: DEBUG/LayoutView1(446): onTouchEvent action:ACTION_DOWN
04-11 03:09:27.629: DEBUG/LayoutView1(446): onTouchEvent action:ACTION_MOVE
04-11 03:09:27.689: DEBUG/LayoutView1(446): onTouchEvent action:ACTION_MOVE
…… //省略過多的ACTION_MOVE
04-11 03:09:27.959: DEBUG/LayoutView1(446): onTouchEvent action:ACTION_UP
------------------------------------------------------------------------------------------------------------------------------
從Log可以看到,由於LayoutView1在攔截第一次down事件時return true,所以後續的事件(包括第一次的down)將由LayoutView1本身處理,事件不再傳遞下去。

3.       LayoutView1,LayoutView2的onInterceptTouchEvent()處理down事件返回false,
MyTextView的onTouchEvent()處理事件返回false
LayoutView2的onTouchEvent()處理事件返回true
----------------------------------------------------------------------------------------------------------------------------
04-11 09:50:21.147: DEBUG/LayoutView1(301): onInterceptTouchEvent action:ACTION_DOWN
04-11 09:50:21.147: DEBUG/LayoutView2(301): onInterceptTouchEvent action:ACTION_DOWN
04-11 09:50:21.147: DEBUG/MyTextView(301): onTouchEvent action:ACTION_DOWN
04-11 09:50:21.147: DEBUG/LayoutView2(301): onTouchEvent action:ACTION_DOWN
04-11 09:50:21.176: DEBUG/LayoutView1(301): onInterceptTouchEvent action:ACTION_MOVE
04-11 09:50:21.176: DEBUG/LayoutView2(301): onTouchEvent action:ACTION_MOVE
04-11 09:50:21.206: DEBUG/LayoutView1(301): onInterceptTouchEvent action:ACTION_MOVE
04-11 09:50:21.217: DEBUG/LayoutView2(301): onTouchEvent action:ACTION_MOVE
…… //省略過多的ACTION_MOVE
04-11 09:50:21.486: DEBUG/LayoutView1(301): onInterceptTouchEvent action:ACTION_UP
04-11 09:50:21.486: DEBUG/LayoutView2(301): onTouchEvent action:ACTION_UP
----------------------------------------------------------------------------------------------------------------------------
可以看到,由於MyTextView在onTouchEvent()中return false,down事件被傳遞給其父view,即LayoutView2的onTouchEvent()方法處理,由於在LayoutView2的onTouchEvent()中return true,所以down事件傳遞並沒有上傳到LayoutView1。注意,後續的move和up事件均被傳遞給LayoutView2的onTouchEvent()處理,而沒有傳遞給MyTextView。

相關文章

聯繫我們

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