在view绘制完成后,要想在和view交互一定就要使用事件了,这些事件包括触屏,按键,以及轨迹球,说起轨迹球,在黑莓的手机上常见,现在触屏出来之后基本上就没有这个东西了。这些事件从屏幕上产生出来,会进行硬件中断,然后交给操作系统,然后由操作系统分发给我们的应用,我们就从frameworlk层开始分析。

首先是由windowmanagerservice接收到之后会使用共享内存和管道和我们的程序进行进程通讯,也就是ViewRoot之前就说过他是管理view的事件的。它存在windowmanager中,当Viewroot调用dispatchPointer方法调用diliverpointerevent就交给了mView的dispatchtouchevent。这个mView就是decorview。这时候decroview调用了一个回调函数的回调callback,这个callback是谁?如果还记得activity的挂载的,在actvity的attach的时候设置了回调就是activity。也就是说这里的回调实际上是activity的dispatchtouchevent。

这个时候开始就要开始事件的分发了,首先要知道一个规则:事件是由布局向下传递的,也就是说先在activity这一层,然后传递给decroview,然后在传递给各个布局。

在activity的dispatch中会传递给decroview的dispatchtouchevent,这时候假如传递下去没有处理,就说明这个事件没有被消费,处理函数都是返回了false。这时候才会交给activity的ontouchevent。这也就说明,虽然事件向下处理,但是是最子的view拥有最高的优先处理权,只有在最里面的view不处理,才会交给外层的布局处理,都不处理才会交给activity处理。

当传递给decroview的时候,就会传递给最外面的布局viewgroup处理,这时候就要说明viewgroup的处理流程了:

tip: 在说处理流程之前有必要说明一下触摸事件:其实触摸事件一般是连续的也就是说actiondown 之后会有actionmove然后有actionup,可能中间不会有actionmove,但是对应的要有actionup。这是一般,特殊情况就是actiondown之后是actioncancel。其实我们事件里没有actioncancel,这个出现是由于出现了actiondown,但是后续actionup一直没有,就比如移动出了view的范围,为了一个完整的动作处理就需要系统自动发一个actioncancel,和up作用是一样的,来完成一个连续动作。防止事件接受不到actionup。

在viewgroup的dispatchtouchevent的时候首先会调用onInterceptTouchEvent这个方法主要是拦截事件的,也就是说这里要是拦截了就不会再向布局里面传递事件了,设置完拦截之后,会便利viewgroup所有的子孩子,然后比对这个事件的x,y点,然后比对是否属于子类view,如果属于就设置一个target为那个view,如果target是空的,这时候就有两种情况:一种是点击事件发生在本viewgroup上,这时候就要调用viewgroup的的ontouchevent方法了。另一种情况就是我们说的触发了cancel。实际cancel就是给我们一个状态的标识符,没有什么处理意义。

传递给子类的dispatchtouchevent之后,就是一个迭代过程,其中viewgroup要不断的传递,直到遇到view。

view处理的时候,也是首先调用dispatchtouchevent,这个过程有很多注意的:首先会看ontouchlistener有没有,有的话就会调用ontouch事件,假如没有或者是事件没有被消费,就传递到view的ontouchevent中,这时候会首先看一下你的clickable或者longclickable是否是可以执行的,因为view的话默认的事件就是这两个,后面的处理actiondown,actionup,actionmove就是处理如何识别这两个事件。actionmove里面主要是处理看move的幅度大不大,假如只是很小的范围移动,就认为是点击事件,否则不是。

要正确的识别点击和长按实际上是使用了消息,在viewconfiguration中定义了点击和长按的时间值。然后在actiondown的时候向消息队列发送了一个延时消息,假如在长按的时间内,执行了up,那么就从队列中去除这条消息,那么长按事件就不会执行,如果down时间超了,那么延时消息自动就执行了。所以长按和短按都是基于这个原理实现的。

总的来说,事件传递主要是由根布局使用dispatchtouchevent分发,然后假如viewgroup要处理,就要使用onInterceptTouchEvent来进行拦截,拦截之后交给ontouchevent处理,假如view要执行就要让ontouchevent返回true,然后在查看你是否设置监听和clickable。也就是说ontouch优先级最高,还要保证你的clickable是true,然后才会执行onclick事件。当然假如是自定义的ontouchevent,那就完全是你自己写事件处理了。

android view :事件的更多相关文章

  1. Android View 事件分发机制 源码解析 (上)

    一直想写事件分发机制的文章,不管咋样,也得自己研究下事件分发的源码,写出心得~ 首先我们先写个简单的例子来测试View的事件转发的流程~ 1.案例 为了更好的研究View的事件转发,我们自定以一个My ...

  2. android view事件分发机制

    首先我们先写个简单的例子来测试View的事件转发的流程~ 1.案例 为了更好的研究View的事件转发,我们自定以一个MyButton继承Button,然后把跟事件传播有关的方法进行复写,然后添加上日志 ...

  3. Android View事件机制一些事

    本文主要讲述: 自己对View事件机制的一些理解 在项目中遇到的一些坑,解决方案 收集了一些View的事件机制问题 事件的分发原理图 对于一个root viewgroup来说,如果接受了一个点击事件, ...

  4. Android View事件分发-从源码分析

    View事件分发-从源码分析 学习自 <Android开发艺术探索> https://blog.csdn.net/qian520ao/article/details/78555397?lo ...

  5. 谈谈我对Android View事件分发的理解

    写这篇博客的缘由.近期因为项目中用到相似一个LinearLayout中水平布局中,有一个TextView和Button,然后对该LinearLayout布局设置点击事件.点击TextView能够触发该 ...

  6. Android View事件分发与传递

    在Android中,人们主要通过手指与系统交互.Android把所有的touch事件都被封装成MotionEvent来进行处理,其中包括了手指点击的位置,时间等信息.其事件类型主要包括:ACTION_ ...

  7. Android View 事件分发机制 源代码解析 (上)

    一直想写事件分发机制的文章,无论咋样,也得自己研究下事件分发的源代码.写出心得~ 首先我们先写个简单的样例来測试View的事件转发的流程~ 1.案例 为了更好的研究View的事件转发,我们自定以一个M ...

  8. android View事件分发机制结论

    原始博客有对源码的分析:http://blog.csdn.net/lmj623565791/article/details/39102591 结论:1.view事件的分发流程: dispatchTou ...

  9. Android View事件传递机制

    ViewGroup dispatchTouchEvent onInterceptTouchEvent onTouch View dispatchTouchEvent onTouch 假设View的层级 ...

  10. Android View事件机制 21问21答

    原文: http://www.cnblogs.com/punkisnotdead/p/5179115.html#3358859 1.View的坐标参数 主要有哪些?分别有什么注意的要点? 答:Left ...

随机推荐

  1. kettle 使用JAVA代码进行执行

    kettle 设计完成之后,可以在设计工具中进行调用,也可以使用java代码进行调用.   1.通过文件方式执行转换.   public static void runTransfer(String[ ...

  2. JQUERY MOBILE 中文API站 和 官方论坛

    中文API站:http://www.jqmapi.com/api1.2/preview/quickstartquide.html 官方论坛:http://bbs.phonegapcn.com/foru ...

  3. Format函数

    Format是一个很常用,却又似乎很烦的方法,本人试图对这个方法的帮助进行一些翻译,让它有一个完整的概貌,以供大家查询之用: 首先看它的声明: function Format(const Format ...

  4. 修改Linux默认启动级别或模式的方法

    冲动的惩罚: 海阔天空: 在linux系统的7种启动级别,默认为X-Window,类似于Windows的窗口模式. 如何修改或变更linux的默认启动级别或模式呢? 以root身份进入Linux,修改 ...

  5. java筛选法求素数

    这本身没什么,代码一堆 发来纪念下而已 本来刚学习java,编写输出100以内的素数 对于我这个有代码运行性能洁癖的人(但是本身又不懂算法)来说,不能忍 于是看了些资料 参考: http://blog ...

  6. jQuery focus、blur事件 添加、删除类名

    jQuery.focusblur = function(ele,className){ var focusblurid = $(ele); focusblurid.focus(function(){ ...

  7. Python学习之路

    从今天开始学习Python,没有什么特殊的目的,只是觉得这门语言比较有意思,既然现在可能也不会用到,那就直接从Python3学起吧! 本人开始学习时,还是喜欢听别人讲,于是又找到了小甲鱼的<零基 ...

  8. iOS 8 以后 MKMapView 代理不执行问题

    因为ios8上,如果你使用了mapView,必须设置mapView的大小,必须把它添加显示在视图上. 可以将frame设为(0,0,0.1,0.1)  

  9. MVC教程相关

    本教程所有文章导航 本系列共10篇文章,翻译自Asp.Net MVC4 官方教程,由于本系列文章言简意赅,篇幅适中,从一个示例开始讲解,全文最终完成了一个管理影片的小系统,非常适合新手入门Asp.Ne ...

  10. css2----兼容----ie67的3像素bug

    发生条件:当浮动元素和非浮动元素相邻 时候,ie67下,两个元素就会多出3像素的间隔,其实是浮动元素产生的margin值 解决办法:1:让没有浮动的元素也浮动: 2:让浮动元素产生margin-*:- ...