在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. linux php 安装 memcache 扩展

    1. memcached依赖于libevent,需要先安装libevent. tar zxvf libevent-2.0.21-stable.tar.gz cd libevent-2.0.21-sta ...

  2. ORACLE 连接SQLSERVER 数据库备忘

    最近工作需要,要从SQL SERVER数据库中同步提取数据. 这里采用了  Oracle Gateway 来连接,折腾了半天,终于搞定,记录下已备下次使用. 基本资料网上都可以搜很多,官网配置说明在这 ...

  3. I/O

    IO流:1:字节流(inputStream:输入流)(outputStream:输出流).2:字符流(reader:输入流)(winter:输出流). 首先判断是输入还是输出(站在计算机的立场):其次 ...

  4. 多线程完成socket

    //服务器端代码 public class Service { //服务器 public static void main(String[] args) { ServerSocket serverSo ...

  5. Mongodb插入记录

    Mongodb下文档的数据结构和JSON基本一样. 所有存储在集合中的数据都是BSON格式. BSON是一种类json的一种二进制形式的存储格式,简称Binary JSON. 插入文档 MongoDB ...

  6. k8s pv

    这个文档描述当前在k8s中PersistentVolumes的使用. 我们建议和volume一起进行了解   Introduction     管理存储和管理计算是截然不同的问题. 持久存储子系统对用 ...

  7. Oracle 添加第二个实例 和 监听

    1.添加第二个实例 配置和移植工具 -->Database Configuration Assistant 然后一步一步创建实例(实例名为ORCL2) 创建成功后会在系统的服务里面有个服务名称为 ...

  8. Redux教程2:链接React

    通过前面的教程,我们有了简单的环境,并且可以运行Redux的程序,也对 如何编写Redux示例 有了初步的印象: 掌握了 使用Redux控制状态转移 ,继而驱动 React 组件发生改变,这才是学习R ...

  9. linux下用eclipse + GDBserver + JLINK 在线调试(ARM11)

    (一)环境: 目标版:TINY6410 OS:centOS6.5 IDE:eclipse luna CDT:v8.3 GDB:V7.5 (二)环境监理 1.安装cenntos:参考其他相关文章,这里重 ...

  10. nim也玩一行流,nim版的list comprehension

    nim 是一门风格类似python的静态编译型语言,官方网站:http://nim-lang.org 如果你想折腾nim的编辑环境,可以用sublime text3 +插件nimlime,notepa ...