当前位置: 代码迷 >> Android >> Android Touch事件传接机制解析
  详细解决方案

Android Touch事件传接机制解析

热度:50   发布时间:2016-05-01 19:48:09.0
Android Touch事件传递机制解析

Android?Touch事件传递机制解析

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

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

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

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

?

?

测试程序界面

?

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

?

状态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事件。

?

?

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

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

?

?

ACTION_DOWN事件处理流程:

?

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

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

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

?

状态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事件处理流程:

?

?

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

?

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

?


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



源代码见附件。

?

?

?

PS.

新浪的不好传附件。

ITEYE的贴图麻烦。

求解决办法。

?

  相关解决方案