您的位置:首页 > 移动开发 > Android开发

Android TouchEvent事件传递机制

2016-05-13 14:08 453 查看

1.触发OnTouch事件的时候的三个方法:

在触发OnTouch事件的时候Android的GroupView会调用如下三个函数:

public boolean dispatchTouchEvent(MotionEvent ev) //用于事件的分发

public boolean onInterceptTouchEvent(MotionEvent ev) // 用于事件的拦截

public boolean onTouchEvent(MotionEvent ev) //处理事件

2.控件中包含哪些方法

在Android中,有一类控件是中还可以包含其他的子控件,这类控件是继承于ViewGroup类,例如:ListView, Gallery, GridView,FrameLayout、LinearLayout。

还有一类控件是不能再包含子控件,例如:Button、TextView、EditText。

这些控件中分别拥有如下的函数

Activity类: Activity ————-包含方法:

dispatchTouchEvent(); onTouchEvent();

View容器(ViewGroup的子类):比如FrameLayout、LinearLayout……ListView、ScrollVIew……这些控件 —————–包含方法:

dispatchTouchEvent(); onInterceptTouchEvent(); onTouchEvent();

View控件(非ViewGroup子类):比如Button、TextView、EditText……这些控件—————- 包含方法:

dispatchTouchEvent(); onTouchEvent();

3.这三个方法的具体作用

1)dispatchTouchEvent()

用来分派事件。

其中调用了onInterceptTouchEvent()和onTouchEvent(),一般不重写该方法

2)onInterceptTouchEvent()

用来拦截事件。———>父View向子View传递

ViewGroup类中的源码默认返回false,表示不拦截该事件,事件将向下传递(传递给其子View),如果子View不是ViewGroup类的控件,则传递给它自己onTouchEvent去处理;

若重写该方法,返回true则表示拦截,事件将终止向下传递,事件由当前ViewGroup类来处理,就是调用该类的onTouchEvent()方法。

3)onTouchEvent()

用来处理事件。———>子View向父View传递

返回true则表示事件已经被处理,事件将终止向上传递(父View);

返回false表示事件没有被处理,则把事件传递给其父View的onTouchEvent()方法来处理

注意点:ACTION_MOVE或者ACTION_UP发生的前提是该控件一定曾经发生了ACTION_DOWN,如果你没有消费ACTION_DOWN,那么系统会认为ACTION_DOWN没有发生过,所以ACTION_MOVE或者ACTION_UP就不能被捕获。也就是说onTouchEvent均返回false,也就是说事件始终没有被消费,那后续事件(ACTION_DOWN的ACTION_MOVE或者ACTION_UP)不会触发,后面demo中会提到。

4.示例

页面布局如下

<?xml version="1.0" encoding="utf-8"?>
<focus.teach.toucheventdemo.LinearLayoutOne xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<focus.teach.toucheventdemo.LinearLayoutTwo
android:layout_width="match_parent"
android:layout_height="match_parent">

<focus.teach.toucheventdemo.MyTextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="ddddd" />
</focus.teach.toucheventdemo.LinearLayoutTwo>

</focus.teach.toucheventdemo.LinearLayoutOne>


很简单的三层,下面通过控制上面三个方法的返回,看事件的传递。

1)LinearLayoutOne,LinearLayoutTwo,MyTextView 的dispatchTouchEvent,onInterceptTouchEvent(MyTextView没有此方法),onTouchEvent均返回false,也就是说事件始终没有被处理,也就是抛给外层的activity的ontouchEvent去处理了,那后续事件(ACTION_DOWN的ACTION_MOVE或者ACTION_UP)也都不会触发。Log信息如下:

05-13 13:04:19.521 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutOne: LinearLayoutOne---dispatchTouchEvent---ACTION_DOWN
05-13 13:04:19.521 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutOne: LinearLayoutOne---onInterceptTouchEvent---ACTION_DOWN
05-13 13:04:19.521 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutTwo: LinearLayoutTwo---dispatchTouchEvent---ACTION_DOWN
05-13 13:04:19.521 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutTwo: LinearLayoutTwo---onInterceptTouchEvent---ACTION_DOWN
05-13 13:04:19.521 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MyTextView: MyTextView---dispatchTouchEvent---ACTION_DOWN
05-13 13:04:19.521 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MyTextView: MyTextView---onTouchEvent---ACTION_DOWN
05-13 13:04:19.522 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutTwo: LinearLayoutTwo---onTouchEvent---ACTION_DOWN
05-13 13:04:19.522 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutOne: LinearLayoutOne---onTouchEvent---ACTION_DOWN
05-13 13:04:19.522 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_DOWN
05-13 13:04:19.532 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE
05-13 13:04:19.999 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE
05-13 13:04:20.015 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE
05-13 13:04:20.048 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE
05-13 13:04:20.056 32126-32126/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_UP


运行结论:LinearLayoutOne,LinearLayoutTwo,MyTextView都只处理了ACTION_DOWN,其余的TouchEvent被外层的Activity处理了

2)LinearLayoutOne,MyTextView 的dispatchTouchEvent,onInterceptTouchEvent(MyTextView没有此方法),onTouchEvent均返回false,LinearLayoutTwo onInterceptTouchEvent返回true,此时ACTION_DOWN应该传递到LinearLayoutTwo 的onTouchEvent,而不是像下传递到MyTextView 的onTouchEvent。同样,onTouchEvent均返回false,也就是说事件始终没有被处理,也就是抛给外层的activity的ontouchEvent去处理了,那后续事件(ACTION_DOWN的ACTION_MOVE或者ACTION_UP)也都不会触发。Log信息如下:

05-13 13:19:22.413 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutOne: LinearLayoutOne---dispatchTouchEvent---ACTION_DOWN
05-13 13:19:22.413 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutOne: LinearLayoutOne---onInterceptTouchEvent---ACTION_DOWN
05-13 13:19:22.413 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutTwo: LinearLayoutTwo---dispatchTouchEvent---ACTION_DOWN
05-13 13:19:22.413 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutTwo: LinearLayoutTwo---onInterceptTouchEvent---ACTION_DOWN
05-13 13:19:22.414 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutTwo: LinearLayoutTwo---onTouchEvent---ACTION_DOWN
05-13 13:19:22.415 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.LinearLayoutOne: LinearLayoutOne---onTouchEvent---ACTION_DOWN
05-13 13:19:22.416 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_DOWN
05-13 13:19:22.434 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE
05-13 13:19:22.503 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE
05-13 13:19:22.518 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE
05-13 13:19:22.552 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE
05-13 13:19:22.567 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_MOVE
05-13 13:19:22.569 14442-14442/focus.teach.toucheventdemo I/focus.teach.toucheventdemo.MainActivity: MainActivity---onTouchEvent---ACTION_UP


运行结论:LinearLayoutOne,LinearLayoutTwo都只处理了ACTION_DOWN,其余的TouchEvent被外层的Activity处理了

其他的几种情况,可以自己去测试。

5.逻辑抽象

拿上面第二个示例,画出对应的逻辑图,如下所示:



demo下载地址:

http://download.csdn.net/detail/dfskhgalshgkajghljgh/9525803

其他的逻辑图就不画了,有问题欢迎提出来。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: