android onTouchEvent和onInterceptTouchEvent区别

来源:互联网 发布:python软件 编辑:程序博客网 时间:2024/05/18 01:44

最近师兄让我分析下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。

原创粉丝点击