1.理解什么是事件
事件:即指用户手指触摸屏幕理解为一个事件,从手指按下到抬起可以理解为一个完整事件;
2.事件的常见概念理解
2.1. 所有的Touch事件都封装到MotionEvent里面
2.2. 事件处理涉及三个方法
a) 传递—-dispatchTouchEvent()函数 派发
b) 拦截——onInterceptTouchEvent()函数 拦截
c) 消费—-onTouchEvent()函数 处理操作
2.3. OnTouchListener优先级在onTouchEvent之上
2.4. 事件类型分为
a) ACTION_DOWN,
b) ACTION_UP,
c) ACTION_MOVE,
d) ACTION_POINTER_DOWN,
e) ACTION_POINTER_UP,
f) ACTION_CANCEL
2.5. 一个触摸事件的metadata包括:
a) 位置
b) 手指数
c) 时间
2.6. 一个手势(Gesture)被定义为以ACTION_DOWN开始,以ACTION_UP结束。
3.事件传递和响应的流程图和实例演示分析
3.1通过流程图看一下事件传递和响应
3.2通过实例分析流程图中的过程
3.2.1首先看一下点击按钮后的输入日志
I/TouchAnalysis: TouchActivity dispatchTouchEvent -- Activity接收到用户触摸事件,向下派发
I/TouchAnalysis: TouchRelativeLayout dispatchTouchEvent -- 最外层的视图TouchRelativeLayout接收到派发事件,向下派发
I/TouchAnalysis: TouchRelativeLayout onInterceptTouchEvent -- 最外层的视图TouchRelativeLayout决定是否自己处理该触摸事件,不拦截继续向下传递
I/TouchAnalysis: TouchSonRelativeLayout dispatchTouchEvent
I/TouchAnalysis: TouchSonRelativeLayout onInterceptTouchEvent
I/TouchAnalysis: TouchView dispatchTouchEvent --最终定位到用户触摸的视图
I/TouchAnalysis: TouchView onTouchEvent Action:0 --最终定位到用户触摸的视图,若触摸的视图不消费(不响应)当前事件,则继续向上传递
I/TouchAnalysis: TouchSonRelativeLayout onTouchEvent
I/TouchAnalysis: TouchRelativeLayout onTouchEvent
I/TouchAnalysis: TouchActivity onTouchEvent Action: 0 --最终向上传递到Activity的onTouchEvent,当检测到触摸事件(down按下操作),未消费时,则(up抬起手势时只在Activity中接收,不在向下传递)
I/TouchAnalysis: TouchActivity dispatchTouchEvent
I/TouchAnalysis: TouchActivity onTouchEventAction: 1
3.2.2视图布局结构
<?xml version="1.0" encoding="utf-8"?> <com.dress.gold.interconnected.checkphone.ui.testui.views.TouchRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ff0000"> <include layout="@layout/view_toolbar" /> <com.dress.gold.interconnected.checkphone.ui.testui.views.TouchSonRelativeLayout android:layout_centerInParent="true" android:layout_width="300dp" android:layout_height="300dp" android:background="#00ff00"> <com.dress.gold.interconnected.checkphone.ui.testui.views.TouchView android:layout_width="100dp" android:layout_height="100dp" android:layout_centerInParent="true" android:background="#0000ff" android:text="TouchView"/> </com.dress.gold.interconnected.checkphone.ui.testui.views.TouchSonRelativeLayout> </com.dress.gold.interconnected.checkphone.ui.testui.views.TouchRelativeLayout>
public class TouchRelativeLayout extends RelativeLayout {
public class TouchSonRelativeLayout extends RelativeLayout
public class TouchView extends View
3.2.3视图显示样式
3.2.4事件传递和响应分析
1)Activity的dispatchTouchEvent方法派发触摸事件
2)TouchRelativeLayout的dispatchTouchEvent方法继续派发事件
3)TouchRelativeLayout的onInterceptTouchEvent方法决定是否派发事件
4)一层一层的事件向下传递
5)最终定位到用户点击的TouchView视图,dispatchTouchEvent接收事件
6)TouchView视图的onTouchEvent,onTouch,onClick接收触摸事件
7)TouchView未对触摸事件处理,则一层一层向上传递,指导Activity中onTouchEvent接收触摸事件
8)Activity检测到所有视图都未处理按下的触摸事件,则抬起事件只在Activity中onTouchEvent中处理,
不在向下传递;
4.具体使用中的集中情况
4.1.TouchView对视图触摸不做处理的情况
不做任何特殊处理的日志信息
用户按下down屏幕
I/TouchAnalysis: TouchActivity dispatchTouchEvent Action:down
I/TouchAnalysis: TouchRelativeLayout dispatchTouchEvent Action:down
I/TouchAnalysis: TouchRelativeLayout onInterceptTouchEvent Action:down
I/TouchAnalysis: TouchSonRelativeLayout dispatchTouchEvent Action:down
I/TouchAnalysis: TouchSonRelativeLayout onInterceptTouchEvent Action:down
I/TouchAnalysis: TouchView dispatchTouchEvent Action:down
I/TouchAnalysis: TouchView onTouchEvent Action:down
I/TouchAnalysis: TouchSonRelativeLayout onTouchEvent Action:down
I/TouchAnalysis: TouchRelativeLayout onTouchEvent Action:down
I/TouchAnalysis: TouchActivity onTouchEvent Action:down
用户抬起up屏幕
I/TouchAnalysis: TouchActivity onTouchEvent Action:up
由于TouchView未处理down事件,则up或者move事件会传给Activity的onTouchEvent中
4.2.TouchView对视图触摸处理的情况
TouchView处理触摸事件的日志信息
在TouchView中的onTouch方法返回true表示视图接收该事件并且处理
@Override public boolean onTouchEvent(MotionEvent event) { Log.i("TouchAnalysis", "TouchView "+" onTouchEvent"+" Action:"+(event.getAction()== MotionEvent.ACTION_DOWN ? "down" : "up")); return true;//super.onTouchEvent(event); }
看一下输出日志:
用户触摸TouchView视图按下事件
I/TouchAnalysis: TouchActivity dispatchTouchEvent Action:down
I/TouchAnalysis: TouchRelativeLayout dispatchTouchEvent Action:down
I/TouchAnalysis: TouchRelativeLayout onInterceptTouchEvent Action:down
I/TouchAnalysis: TouchSonRelativeLayout dispatchTouchEvent Action:down
I/TouchAnalysis: TouchSonRelativeLayout onInterceptTouchEvent Action:down
I/TouchAnalysis: TouchView dispatchTouchEvent Action:down
I/TouchAnalysis: TouchView onTouchEvent Action:down
Activity看到TouchView处理了down事件,则会将up事件继续向下传递
I/TouchAnalysis: TouchActivity dispatchTouchEvent Action:upI/TouchAnalysis: TouchRelativeLayout dispatchTouchEvent Action:up
I/TouchAnalysis: TouchRelativeLayout onInterceptTouchEvent Action:up
I/TouchAnalysis: TouchSonRelativeLayout dispatchTouchEvent Action:up
I/TouchAnalysis: TouchSonRelativeLayout onInterceptTouchEvent Action:up
I/TouchAnalysis: TouchView dispatchTouchEvent Action:up
I/TouchAnalysis: TouchView onTouchEvent Action:up
TouchView接收到up事件
down事件在哪里被处理则,up或者move事件也会到哪里处理;
4.2.TouchView视图上层视图拦截触摸处理的情况
在TouchView上一层TouchSonRelativeLayout中拦截视图并处理触摸事件
@Override public boolean onInterceptTouchEvent(MotionEvent event) { Log.i("TouchAnalysis", "TouchRelativeLayout "+" onInterceptTouchEvent"+" Action:"+(event.getAction()== MotionEvent.ACTION_DOWN ? "down" : "up")); return true;//super.onInterceptTouchEvent(event); } @Override public boolean onTouchEvent(MotionEvent event) { Log.i("TouchAnalysis", "TouchSonRelativeLayout "+" onTouchEvent"+" Action:"+(event.getAction()== MotionEvent.ACTION_DOWN ? "down" : "up")); return true;//super.onTouchEvent(event); }
输出日志如下:
I/TouchAnalysis: TouchActivity dispatchTouchEvent Action:down
I/TouchAnalysis: TouchRelativeLayout dispatchTouchEvent Action:down
I/TouchAnalysis: TouchRelativeLayout onInterceptTouchEvent Action:down
I/TouchAnalysis: TouchSonRelativeLayout dispatchTouchEvent Action:down
I/TouchAnalysis: TouchSonRelativeLayout onInterceptTouchEvent Action:down
I/TouchAnalysis: TouchSonRelativeLayout onTouchEvent Action:down
I/TouchAnalysis: TouchActivity dispatchTouchEvent Action:up
I/TouchAnalysis: TouchRelativeLayout dispatchTouchEvent Action:up
I/TouchAnalysis: TouchRelativeLayout onInterceptTouchEvent Action:up
I/TouchAnalysis: TouchSonRelativeLayout dispatchTouchEvent Action:up
I/TouchAnalysis: TouchSonRelativeLayout onTouchEvent Action:up
会发现事件传递到TouchSonRelativeLayout以后则不在向下传递而是把事件传给onTouchEvent处理,up和move事件也会传给TouchSonRelativeLayout处理;
4.3基于上面几种情况的分析
事件传递机制最终的目的就是为了某个视图可以接收到触发View的onClick监听和onTouch监听,做一些处理操作;
1)首先一个触摸事件最先传递给Activity的dispatchTouchEvent方法进行派发;
a)事件由父视图传递给子视图;
b)事件在传递过程中,父视图可以拦截事件,停止向子视图派发;
2)Activity.dispatchTouchEvent
a)是所有事件的入口,从这里开发进行分发;
b)分发过程中逐级向下层视图传递;
3)Activity.onTouchEven,当所有视图都不处理down事件时,Activity的onTouchEvent方法是最后接收触摸事件,否则不接收不到触摸事件;
4)View通过对ACTION_DOWN事件来表示感兴趣,Up或者Move事件才会传递给View,否则Up或者Move事件不会传递给View,最终传递给Activity的onTouchEvent中;
5.ViewGroup
ViewGroup通过dispatchTouchEvent方法进行事件的派发,onInterceptTouchEvent方法最终决定是否拦截自己处理,不拦截返回false继续向下传递,拦截返回true则不在向下传递,自己处理;
6.View
a)如何和事件有关,则首先会调用dispatchTouchEvent;
b)如何down事件向下传递的过程中一直没有被处理,则会反向调用对应onTouchEvent方法;
7).View中onTouchListener中onTouch优先级高于onToucEvent的;