在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. python中引用

    python中的可变类型与不可变类型: 在讲python深浅拷贝之前,我们首先应该明白python中元素的类型:主要分为可变类型和不可变类型. 可变类型,就是值可以改变的类型有两个: 列表:list ...

  2. [原创]C#应用WindowsApi实现查找(FindWindowEx)文本框(TextBox、TextEdit)。

    /// <summary> /// 获取文本框控件 /// </summary> /// <param name="hwnd">文本框所在父窗口 ...

  3. SQL经典面试题及答案

    1.一道SQL语句面试题,关于group by表内容:2005-05-09 胜2005-05-09 胜2005-05-09 负2005-05-09 负2005-05-10 胜2005-05-10 负2 ...

  4. GDB配置与.gdbinit的编写

    GDB配置与.gdbinit的编写 当 GDB(即 GNU Project Debugger)启动时,它在当前用户的主目录中寻找一个名为 .gdbinit 的文件:如果该文件存在,则 GDB 就执行该 ...

  5. codeforces 727F. Polycarp's problems

    题目链接:http://codeforces.com/contest/727/problem/F 题目大意:有n个问题,每个问题有一个价值ai,一开始的心情值为q,每当读到一个问题时,心情值将会加上该 ...

  6. PHPExcel读取Excel文件的实现代码

    <?php require_once 'PHPExcel.php'; /**对excel里的日期进行格式转化*/ function GetData($val){ $jd = GregorianT ...

  7. JSFuck奇葩的js编码

    以前对黑客很崇拜,黑客的世界无比精彩.最近为了炫耀,想起了这段特殊的代码. [][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[ ...

  8. UITableViewCell里面separator的设置

    最近cell显示的时候左边一直有15个像素的偏移,查了下面的方法 //1. 不管用 [self.tableView setSeparatorInset:UIEdgeInsetsZero]; // 2. ...

  9. Linux学习 : 自己写bootloader

    一.bootloader 目标:启动内核 基本功能: ①初始化硬件:关看门狗.设置时钟.设置SDRAM.初始化NAND FLASH ②image比较大需要重定位到SDRAM ②将内核从NAND FLA ...

  10. Console命令详解,让调试js代码变得更简单

    Firebug是网页开发的利器,能够极大地提升工作效率. 但是,它不太容易上手.我曾经翻译过一篇<Firebug入门指南>,介绍了一些基本用法.今天,继续介绍它的高级用法. ======= ...