有关自定义View的学习(View的点击事件传递流程)


1、安卓OnTouchListener,onTouchEvent,onClickListener执行顺序

首先我们相对比较熟悉的是处理滑动冲突时候的三个事件(ViewGroup 继承 View)

(View是没有onInterceptTouchEvent方法的),先看看ViewGroup和View的事件流程方法:

ViewGroup

1. dispatchTouchEvent(分发touch事件)

2. onInterceptTouchEvent(拦截touch事件)

3. onTouchEvent(消费事件)

View

1. dispatchTouchEvent(分发touch事件)

2. onTouchEvent(消费事件)

       这些知识点想必大家比较熟悉了,这些知识具体的细节我在安卓开发艺术探索上看过较为详细的介绍,里面说到了如何处理滑动冲突,并且举了两个示例,一个是横向滑动冲突,一个是竖向的滑动冲突。

先详细介绍一下这三个方法吧

事件分发需要View的三个重要方法来共同完成:

public boolean dispatchTouchEvent(MotionEvent event)

通过方法名我们不难猜测,它就是事件分发的重要方法。那么很明显,如果一个MotionEvent传递给了View,那么dispatchTouchEvent方法一定会被调用!

返回值:表示是否消费了当前事件。可能是View本身的onTouchEvent方法消费,也可能是子View的dispatchTouchEvent方法中消费。返回true表示事件被消费,本次的事件终止。返回false表示View以及子View均没有消费事件,将调用父View的onTouchEvent方法

public boolean onInterceptTouchEvent(MotionEvent ev)

事件拦截,当一个ViewGroup在接到MotionEvent事件序列时候,首先会调用此方法判断是否需要拦截。特别注意,这是ViewGroup特有的方法,View并没有拦截方法

返回值:是否拦截事件传递,返回true表示拦截了事件,那么事件将不再向下分发而是调用View本身的onTouchEvent方法。返回false表示不做拦截,事件将向下分发到子View的dispatchTouchEvent方法。

public boolean onTouchEvent(MotionEvent ev)

真正对MotionEvent进行处理或者说消费的方法。在dispatchTouchEvent进行调用。

返回值:返回true表示事件被消费,本次的事件终止。返回false表示事件没有被消费,将调用父View的onTouchEvent方法

可以使用下面的伪代码来表示这个流程:


有关自定义View的学习(View的点击事件传递流程)
事件分发伪代码

我们常用的按钮的onclick事件都是在ACTION_UP以后才被调用的。(这点要注意)


跑题了跑题了,我今天想做的笔记其实是有关OnTouchListener中的onTouch方法。因为我在看别人的源码的时候发现了ToolBar的透明设置(感觉这种UI很好,所以从网上搜了一下)我看的是这篇文章;在这里他说了基础程序员都懂onTouchListener的onTouch方法会在onTouchEvent(最终消费事件)之前执行;吓得我赶紧回想下我是不是知道,发现我真不知道,(此时的内心和躺在草坪上的梅西一样慌),所以我就感觉去网上搜索了一下有关知识点,还好搞懂了。不能降低自己的自我要求啊。他这里是为了处理ToolBar的拦截点击事件,因为Toolbar源码中的onTouchEvent的最终返回值是true。即默认拦截消费点击事件。所以文章的作者在处理的时候给toolbar设置了监听事件,重写了onTouch方法,在里面调用了下层布局的dispatchTouchEvent方法让他传递即可。

那么他们之间到底是什么关系呢(知识点知识点啊朋友们)安卓OnTouchListener,onTouchEvent,onClickListener执行顺序 - CSDN博客,如果想详细了解可以看看这篇文章。

这里举了示例,首先作为一名有志向的程序员,我们应该知道onClickListener的执行时间在UP之后,即手指抬起之后。

其次我们接着看dispatchTouchEvent方法,如果有OnTouchListener的话OnTouchListener是比onTouchEvent先执行的,当然前提是OnTouchListener返回false,即OnTouchListener并没有处理事件,所以事件继续分发。这个又让我先搞了自定义View中的几个方法(onMeasure,onDraw,onLayout)但是我们很多时候自定义绘画形状的时候会用到另一个方法,onSizeChanged方法,该方法的调用在onMeasure()之后,此时已经知道了View的宽高,所以可以在该方法中来获取高度。用来自定义一些东西。

这里有些像,本身我们只有三个方法就够了,但是如果我们需要拦截可以用到OnTouchListener的onTouch方法(时刻牢记他是在onTouchEvent之前执行)(时刻牢记他是在onTouchEvent之前执行)(时刻牢记他是在onTouchEvent之前执行)重要的事说三遍。所以我们可以在最终消费事件之前搞事情。搞事情。搞事情。

这次的知识点就写到这(也算是巩固自己的记忆,防止以后忘记回来再看能够快速的回想起来)

上一篇:设计模式中的观察者模式


下一篇:LeetCode 编程