Android事件传递机制和响应机制

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   dispatchTouchEvent Action: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:up
I/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的;




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值