View的事件分发机制

View事件的分发机制由三个方法共同完成,这三个方法是:

public boolean  dispatchTouchEvent(MotionEvent ev);

public boolean onInterceptTouchEvent(MotionEvent ev);

public boolean onTouchEvent(MotionEvent ev);

它们之间的关系可以用下面的伪代码表示:

public boolean dispatchTouchEvent(MotionEvent ev)
{
    boolean consume=false;        if(onInterceptTouchEvent(ev))
    {
        consume=onTouchEvent(ev);
    }
    else
    {
        consume=child.dispatchTouchEvent(ev);
    }
    return consume;
}

从上面的伪代码中可以看出点击事件的传递规则是这样的:
点击事件的传递是由外向内的,最先接受的到事件的是最外层的ViewGroup,这时候会调用dispatchTouchEvent方法(如果能够接收到事件,那么此方法一定会被调用),如果onInterceptTouchEvent方法返回的是true,那么就说明它要拦截这个事件,于是这个事件就交给该ViewGroup处理,也就是调用onTouchEvent方法。

相反的,如果onInterceptTouchEvent的方法返回的是false,那么就说明该ViewGroup不拦截事件,事件会传递给它的子元素,子元素的dispatchTouchEvent方法会被调用,以此类推一直进行下去,直到事件最终被处理。

如果该事件已经交给子view处理,但是子view的onTouchEvent方法返回了false(没有处理事件,或者处理事件失败了),那么父容器的onTouchEvent就会被调用(我们可以形象的认为下级处理事件失败,那么就由上级进行处理),以此类推上去,如果所有的元素都不处理这个事件,那么这个事件最终会传递给activity,activity的onTouchEvent方法会被调用。

事件分发的时候传递顺序为Activity->Window->View.

由上面的分析过程我们可以知道上面三个方法分别的作用是什么:

dispatchTouchEvent:是用来分发事件的,如果事件能够传递到该view,那么该view的dispatchTouchEvent方法一定会被调用。

onInterceptTouchEvent:用来判断是否拦截事件,返回true表示拦截,返回false表示不拦截。一旦事件被该view拦截,那么同一个事件序列中该方法不会再被调用。

onTouchEvent:用来处理事件,返回true表示消耗,false表示不消耗。如果不消耗,那么同一个事件序列中当前的view无法再接收到事件。

何为同一个事件序列:手指触摸屏幕的那一刻到手指离开屏幕的那一刻,这个过程中产生的一系列事件。

(例如当你在滑动的时候:ACTION_DOWN->ACTION_MOVE->ACTION_MOVE...->ACTION_UP)

onTouchEvent,OnTouchListener,OnClickListener的优先级:

OnTouchListener>onTouchEvent>OnClickListener

如何说呢:如果该view处理事件的时候设置了OnTouchListener,那么OnTouchListener方法里面的onTouch会被回调,若是onTouch返回了true,那么onTouchEvent不会被调用,反之onTouchEvent会被调用,此时若是设置了OnClickListener,那么在onTouchEvent中onClick方法会被调用。

有几个需要注意的小点:

1、一个view一旦开始处理事件,若它不消耗ACTION_DOWN事件(onTouchEvent返回了false),那么同一个事件序列的其他事件都不会再交给它处理,事件会交到父元素去处理(父元素的onTouchEvent会被调用)。若是该view消耗了ACTION_DOWN事件,但是不消耗其他事件,那么事件就会消失,最终这些消失的点击事件就会传递给Activity处理。

2、ViewGroup默认不拦截所有的事件,它的onInterceptTouchEvent默认返回了false。

3、view没有onInterceptTouchEvent方法,一旦有事件传递给它,那么它的onTouchEvent方法就会被带调用。

4、view的onTouchEvent方法默认返回true,也就会说view默认会消耗事件,除非它是不了点击的,也就是它的clickable和longClickable同时被设置为false。事实上view的longClickable属性默认为false,clickable则要分情况,比如Button的clickable属性默认为true,TextView的clickable属性默认为false。

5、view的enable属性不会影响onTouchEvent的默认返回值。即使其为disable状态,只要它的clickable或者longClickable有一个为true,那么它的onTouchEvent就返回true。

6、onClick会发生的前提是当前的View是可点击的,并且它收到了down和up事件。

时间: 2024-10-10 04:17:03

View的事件分发机制的相关文章

Android View的事件分发机制

准备了一阵子,一直想写一篇事件分发的文章总结一下.这个知识点实在是太重要了. 一个应用的布局是丰富的,有TextView,ImageView,Button等.这些子View的外层还有ViewGroup.如RelativeLayout.LinearLayout.作为一个开发人员,我们会思考.当点击一个button,Android系统是如何确定我点的就是button而不是TextView的?然后还正确的响应了button的点击事件. 内部经过了一系列什么过程呢? 先铺垫一些知识能更加清晰的理解事件分

View的事件分发机制解析

引言 Android事件构成 在Android中,事件主要包含点按.长按.拖拽.滑动等,点按又包含单击和双击,另外还包含单指操作和多指操作.全部这些都构成了Android中的事件响应.总的来说.全部的事件都由例如以下三个部分作为基础: 按下(ACTION_DOWN) 移动(ACTION_MOVE) 抬起(ACTION_UP) 全部的操作事件首先必须运行的是按下操作(ACTION_DOWN).之后全部的操作都是以按下操作作为前提,当按下操作完毕后.接下来可能是一段移动(ACTION_MOVE)然后

13.View的事件分发机制——dispatchTouchEvent详解

在前面的第二篇文章中,我们提过,View的事件分发是一种委托思想:上层委托下层,父容器委托子元素来处理这个流程.接下来,我们就将深入去学习View的事件分发机制. 1.事件的传递流程 事件,在Android中对应的类是MotionEvent,因此,我们要分析的就是MotionEvent这个类.对点击事件的分发,其实就是对MotionEvent的对象进行处分发.所以,当一个MotionEvent产生以后(从驱动读取),系统需要把这个事件传递给一个具体的View,这个传递的过程就是分发过程,点击事件

Android开发-分析ViewGroup、View的事件分发机制、结合职责链模式

介绍 上一篇博客职责链/责任链模式(Chain of Responsibility)分析理解和在Android的应用 介绍了职责链模式,作为理解View事件分发机制的基础. 套用职责链模式的结构分析,当我们的手指在屏幕上点击或者滑动,就是一个事件,每个显示在屏幕上的View或者ViewGroup就是职责对象,它们通过Android中视图层级组织关系,层层传递事件,直到有职责对象处理消耗事件,或者没有职责对象处理导致事件消失. 关键概念介绍 要理解有关View的事件分发,先要看几个关键概念 Mot

Android view 的事件分发机制

1 事件的传递顺序是 Activity -> Window -> 顶层View touch 事件产生后,最先由 activity 的 dispatchTouchEvent 处理 /** * Called to process touch screen events. You can override this to * intercept all touch screen events before they are dispatched to the * window. Be sure to

Android中View的事件分发机制

简介 事件也称MotionEvent,事件分发机制就是对MotionEvent事件的分发过程,即当一个MotionEvent发生之后,系统需要把这个事件传递给一个具体的View. 点击事件的分发过程由三个函数共同完成: dispatchTouchEvent(DTE) - 进行事件的分发,如果时间能够传递给当前View,该方法会被调用,返回结果受当前view的onTouchEvent, 子View的dispatchTouchEvent影响,表示是否消耗当前事件. onInterceptTouchE

Android View体系(五)从源码解析View的事件分发机制

相关文章 Android View体系(一)视图坐标系 Android View体系(二)实现View滑动的六种方法 Android View体系(三)属性动画 Android View体系(四)从源码解析Scroller 前言 三年前写过事件分发机制的文章但是写的不是很好,所以重新再写一篇,关于事件分发机制的文章已经有很多,但是希望我这篇是最简洁.最易懂的一篇. 1.处理点击事件的方法 View的层级 我们知道View的结构是树形的结构,View可以放在ViewGroup中,这个ViewGro

Android View的事件分发机制探索

概述 Android事件传递机制也是Android系统中比较重要的一块,事件类型有很多种,这里主要讨论TouchEvent的事件在framework层的传递处理机制.因为对于App开发人员来说,理解framework层的事件传递机制,就差不多了. 带着问题来思考整个事件分发过程. 1.为什么要有事件分发过程? 当Android设备的屏幕,接收到触摸的动作时,屏幕驱动把压力信号(包括压力大小,压力位置等)传递给系统底层,然后操作系统经过一系列的处理,然后把触摸事件一层一层的向上传递,最终事件会被准

Android 开发艺术探究V第三章之view的事件分发机制

在介绍点击事件的传递机制,首先我们要分析的对象就是MOtionEvent,即点击事件,(当点击屏幕时由硬件传递过来,关于MotionEvent在View的基础知识中做了介绍),所谓的点击事件的分发就是MotionEvent的分发过程.即当一个MoTionEvent产生以后,系统需要把这个事件具体传递给一个具体的View,而这个传递过程就是分发过程,点击事件传递过程有三个很重要的方法,下面先来介绍这几个方法.  public boolean dispatchTouchEvent(MOtionEve