Android自定义View随笔-生活工作点滴事件分发

Android事件分发机制

2019-07-13  本文已影响9人  NoBugException

Android事件分发机制算是Android高级篇的基础了,程序猿一定要对其有所了解。

(1)确定事件分发的对象

当用户点击View或ViewGroup时就产生了触摸(Touch)事件,Touch相关的细节被封装成了MotionEvent对象。当我们自定义View时经常重写onTouchEvent方法,比如:

@Override
public boolean onTouchEvent(MotionEvent event) {

    switch (event.getAction()){
        case MotionEvent.ACTION_DOWN:
            break;
        case MotionEvent.ACTION_MOVE:
            break;
        case MotionEvent.ACTION_CANCEL:
            break;
        case MotionEvent.ACTION_UP:
            break;

    }
    return super.onTouchEvent(event);
}

onTouchEvent可以监听到触摸(Touch)事件。

常用的Touch事件有四种:

View事件的基本流程是:

用户按下View,触发ACTION_DOWN事件-->用户拖动或滚动View,触发ACTION_MOVE事件-->用户抬起,放开View,触发ACTION_UP事件。
ACTION_CANCEL事件的触发非人为触发,也许是程序猿代码中主动取消,也许是发生了异常导致取消。

(2)事件分发的本质

本质上是将点击时间的出来传递到View本身去处理,这个过程叫做分发过程。

(3)事件传递的载体

事件传递的载体是:Activity(Window)、ViewGroup、View。

假设点击一个按钮,事件的传递顺序是:Activity(Window)-->ViewGroup-->View

下图是Activity、ViewGroup、View的层级图,其实Activity上面还有一层叫PhoneWindow,但不是本章重点。

图片.png

请先记住触摸事件的传递顺序:Activity(Window)-->ViewGroup-->View

(4)事件的分发由哪些方法协调?

事件的分发由dispatchTouchEvent()onInterceptTouchEvent()onTouchEvent()相互协调的。

事件分发到最后,总是由 onTouchEvent()来处理触摸事件。

它的返回值代表的意义:
[true]:直接结束
[super或false]:执行上级的onTouchEvent()方法

事件的分发总是由这个方法开始,根据不同的返回值做出相应的处理:
[true]:直接结束事件的分发
[false]:执行上级的onTouchEvent()方法去处理触摸事件,最后结束事件的分发
[super]:继续分发事件

只有在ViewGroup中才有这个方法,这个方法专门负责事件的拦截工作,根据返回值处理不同的结果:
[true]:执行ViewGroup的onTouchEvent()事件;
[super或false]:执行View的dispatchTouchEvent()方法

(5)事件在Activity中是如何处理的?

前提条件:Activity中有一个按钮(View),按钮在一个布局(ViewGroup)中。

我们都知道触摸事件的传递顺序:Activity(Window)-->ViewGroup-->View,那么在Activity中事件是如何处理的呢?

Activity中有一个dispatchTouchEvent方法,当有触摸事件时,最先执行的方法就是dispatchTouchEvent,它的返回类型是一个boolean类型,默认情况下返回super.dispatchTouchEvent(ev),当返回super.dispatchTouchEvent(ev)时,事件将传递给ViewGroup,但是如果返回true或者false时,事件就会直接结束,不会传递给ViewGrou,更不会传递给View。

比如,在Activity中重写dispatchTouchEvent

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    return true;
}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    return false;
}

这种情况下,按钮是不可能监听到点击事件的,一般我们不会在Activity中重写dispatchTouchEvent方法,就默认返回super.dispatchTouchEvent(ev),让它把事件传递到ViewGroup即可。

(6)事件在ViewGroup中是如何处理的?

当事件从Activity传递到ViewGroup之后,ViewGroup是如何处理这个事件的呢?

在ViewGroup中,事件首先被分发到ViewGroup的dispatchTouchEvent方法:

onInterceptTouchEvent的返回值解析如下:

onTouchEvent的返回值解析如下:

(7)事件在View中是如何处理的?

在View中,事件首先被分发到View的dispatchTouchEvent方法:

(8)事件分发流程图(是重点,要记住)

以上这张图要记住,上面说了那么多废话,记不住不要紧,只要将这张图记住就可以了。

事件分发流程图.png
(9)总结

[本章完...]

上一篇 下一篇

猜你喜欢

热点阅读