`

Android Touch事件传递机制解析

阅读更多

Android Touch事件传递机制解析

android系统中的每个 View 的子类都具有下面三个和 TouchEvent 处理密切相关的方法:

1 public boolean dispatchTouchEvent(MotionEvent ev)   这个方法用来分发 TouchEvent

2 public boolean onInterceptTouchEvent(MotionEvent ev)  这个方法用来拦截 TouchEvent

3 public boolean onTouchEvent(MotionEvent ev)  这个方法用来处理 TouchEvent

 

 

测试程序界面

 

下述3 Layout 包含关系见如下界面图。

 

状态1 :由 center 处理 Touch 事件

Xml如下:

<? xml   version = "1.0"   encoding = "utf-8" ?>

< LinearLayout   xmlns:android = "http://schemas.android.com/apk/res/android"

     android:layout_width = "fill_parent"

     android:layout_height = "fill_parent"

     android:orientation = "vertical"   >

     < dk.touch.MyLayout

         android:id = "@+id/out"

         android:layout_width = "fill_parent"

         android:layout_height = "fill_parent"

         android:gravity = "center"

             android:background = "#ff345600"

          >

         < dk.touch.MyLayout

             android:id = "@+id/middle"

             android:layout_width = "200dp"

             android:layout_height = "200dp"

             android:gravity = "center"

             android:background = "#ff885678"

             >

             < dk.touch.MyLayout

                 android:id = "@+id/center"

                 android:layout_width = "50dp"

                 android:layout_height = "50dp"

                 android:background = "#ff345678"

                 android:focusable = "true"

                 android:focusableInTouchMode = "true"

                 android:clickable = "true"

                  >

             </ dk.touch.MyLayout >

         </ dk.touch.MyLayout >

     </ dk.touch.MyLayout >

</ LinearLayout >

 

 

注意:只有center这个部分是会处理/消费 Touch事件。

 

 

事件传递记录结果如上图。

由于Down Move Up 事件处理流程略微不同,故分开分析。

 

 

ACTION_DOWN事件处理流程:

 

首先触摸事件发生时( ACTION_DOWN ),由系统调用 Activity dispatchTouchEvent 方法,分发该事件。根据触摸事件的坐标,将此事件传递给 out dispatchTouchEvent 处理 ,out 则调用 onInterceptTouchEvent  判断事件是由自己处理,还是继续分发给子 View 。此处由于 out 不处理 Touch 事件,故根据事件发生坐标,将事件传递给 out 的直接子 View (即 middle )。

Middle Center 中事件处理过程同上。但是由于 Center 组件是 clickable   表示其能处理Touch 事件,故 center 中的 onInterceptTouchEvent 方法将事件传递给 center 自己的 onTouchEvent 方法处理。至此,此 Touch 事件已被处理,不继续进行传递。

Move和  up  事件处理流程类似,但是再 center 内的 dispatchTouchEvent 方法内被直接分配给 onTouchEvent 处理,不需经过 onInterceptTouchEvent 判断。这是由于, android 系统中将 1 down 事件、 n move 事件、 1 up 事件整体作为一次逻辑上的触控操作, Down 事件已经确定了处理事件的对象,则后续的 move up 事件也确定了处理事件的对象。

 

状态2 :都不处理事件

Xml如下:

<? xml   version = "1.0"   encoding = "utf-8" ?>

< LinearLayout   xmlns:android = "http://schemas.android.com/apk/res/android"

     android:layout_width = "fill_parent"

     android:layout_height = "fill_parent"

     android:orientation = "vertical"   >

     < dk.touch.MyLayout

         android:id = "@+id/out"

         android:layout_width = "fill_parent"

         android:layout_height = "fill_parent"

         android:gravity = "center"

             android:background = "#ff345600"

          >

         < dk.touch.MyLayout

             android:id = "@+id/middle"

             android:layout_width = "200dp"

             android:layout_height = "200dp"

             android:gravity = "center"

             android:background = "#ff885678"

             >

             < dk.touch.MyLayout

                 android:id = "@+id/center"

                 android:layout_width = "50dp"

                 android:layout_height = "50dp"

                 android:background = "#ff345678"

                  >

             </ dk.touch.MyLayout >

         </ dk.touch.MyLayout >

     </ dk.touch.MyLayout >

</ LinearLayout >

 

 

 

 

 

 

轻触 center部分 logcat 输出结果

 

Action_down事件处理流程:

 

 

事件处理流程大致同上,区别是此状态下,所有组件都不会处理事件,事件并不会被center onTouchEvent 方法“消费”,则事件会层层逆向传递回到 Activity ,若 Activity 也不对此事件进行处理,此事件相当于消失了(无效果)。

 

对于后续的move up 事件,由于第一个 down 事件已经确定由 Activity 处理事件,故 up 事有由 Activity dispatchTouchEvent 直接分发给自己的 onTouchEvent 方法处理。

 


图片参见 : http://blog.sina.com.cn/s/blog_a0dfaa980100wn1w.html



源代码见附件。

 

 

 

PS.

新浪的不好传附件。

ITEYE的贴图麻烦。

求解决办法。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics