前言

随着科学技术的发展,智能手机早已成为我们当代人身边不可缺少的“伙伴”之中的一个,堪比对象女友。每天我们对着手机反复的做着点击滑动操作,而手机则随着我们的操作给我们展示她的精彩。



废话到此结束。

看到这里,即使不是作为移动端码农的你也应该知道触摸事件对手机(经典键盘机除外)的重要性了。

什么是触摸事件

顾名思义。就是触摸手机屏幕后产生的事件。这时候请你拿出手机。点击屏幕中的某个按钮(不要松手),移动一段距离。松手。

这个过程通常会产生例如以下几个事件:

  1. 点击(Down)事件
  2. 移动(Move)事件
  3. 松手(Up)事件

Android为我们封装好了一个触摸事件类MotionEvent,上述的三个过程分别相应着MotionEvent中的MotionEvent.ACTION_DOWNMotionEvent.ACTION_MOVEMotionEvent.ACTION_UP事件类型,我们能够以此来实现不同的逻辑,即事件的分发处理。所谓触摸事件的分发,实际上能够理解为MotionEvent事件的分发过程,即当一个MotionEvent产生了之后,系统须要把这个事件传递给一个详细的View,而这个传递的过程就是分发过程。

事件三剑客

一般事件的分发过程是由事件三剑客(方法)来共同完毕的。

/**
* 剑客一:用于事件的分发
*/
public boolean dispathTouchEvent(MotionEvent ev) /**
* 剑客二:在剑客一中被调用,用于事件的拦截
*/
public boolean onInterceptTouchEvent(MotionEvent ev) /**
* 剑客三:在剑客一中被调用。处理点击事件。true:消耗了当前事件 false:当前view无
* 法再次接收事件
*/
public boolean onTouchEvent()(MotionEvent ev)

三剑客的关系例如以下图所看到的(以Activity的dispathTouchEvent为例)



分析可知:

1. 触摸事件ev类收到点击的ACTION,会回调onUserInteraction方法,一般项目中我们把一些须要用户開始触摸时就须要执行的任务代码放在这里。

2. 接下来触摸事件ev会传递给Activity窗体绑定的根视图rootView(View/ViewGroup)。如果根视图也有子视图。事件ev会一级一级的分发下去,如果在这个过程中ev被消耗了,事件就此结束分发,否则进入步奏3。

3. 全部的视图布局都没有消耗掉ev事件。就会调用Activity的onTouchEvent()方法。以下会详细讲诉。

Android界面简析

在详细讲诉前,我们先来了解下的android的界面架构。如果说手机是一个学校,那么手机中的每一个APP(应用)都是学校里的一道道独特风景,正是它们,构成了学校的魅力。而每一个APP都是由一个个Activity组成的。

还是在说废话…


例如以下图所看到的,我们清晰的看到每一个Activity都会包括一个Window对象。而window对象通常由PhoneWindow来实现。

PhoneWindow将一个DecorView设置为整个应用窗体的根View。它将屏幕分成两部分。一个是TitleView。还有一个是ContentView(也就是大家熟悉的ContentView布局)。

ContentView是一个ID为contentFrameLayout,而我们一直写的activity_xx.xml布局就是设置在这样一个FrameLayout里。



DecorView将要显示的详细内容呈如今了PhoneWindow上。这里面的全部View的监听事件(点击、滑动等操作)都通过一个名为WindowManagerService来进行接收(详细可看深入理解android卷三),并通过Activity来回调相应的监听。

为了让大家更好的理解。我们来写一个小demo例如以下

执行结果如图

小场景。见真理

场景一

我们写一个最简单的demo例如以下



执行程序,点击button,看到log输出例如以下:



改动dispathTouchEvent,直接return false

执行程序,点击button,是不是看到控制台什么都没有输出。可见事件传递到activity的根视图就被结束分发了。以下已场景二来详细探究下这个过程。

场景二

假如在大学中。学校交给了数学老师一个任务。老师讲这项任务布置给了女班长。而女班长又将这个任务交给了帅气的我。我千辛万苦的将这个任务完毕了,然后交给了女班长,女班长认为完毕的不错,夸了帅气的我几句(暗恋上了),然后将任务提交给了老师,老师看了下也认为完毕的不错,就把任务提交给学校了。

根据上面的场景,我们设计一个场景实比例如以下

  1. 老师——TeacherViewGroup
  2. 女班长——MonitressViewGroup
  3. 帅气的我——HandsomeMyView

布局层次例如以下图所看到的



TeacherViewGroup和MonitressViewGroup代码例如以下。重写了三剑客方法

HandsomeMyView代码例如以下,view是没有剑客2(方法)onInterceptTouchEvent()

点击帅气的我能够看见log打印例如以下

能够看见一般事件都有两个过程

  • 传递过程 : 老师(TeacherViewGroup)——>女班长(MonitressViewGroup)——>帅气的我(HandsomeMyView)
  • 处理过程 : 帅气的我(HandsomeMyView)——>女班长(MonitressViewGroup)——>老师(TeacherViewGroup)

传递的过程方法:剑客1(dispatchTouchEvent)、剑客2(onInterceptTouchEvent)

处理的过程方法:剑客3(onTouchEvent)

为了让大家更好的理解。整理视图例如以下:

从中我们看出触摸事件ev会依照子View增加ViewGroup先后顺序相反的顺序。依次有机会去消费此触摸事件ev。即最后增加的最先有机会消费此触摸事件(消费的前提是,触摸点在这个子View的视图范围之内)。简而言之,传递由外向内,消费(处理)由内向外。

在前面的事件三剑客中细心的同学会发现,他们的返回值都是boolean类型,那么true和false分别代表什么意义呢?

在这里我先告诉大家结论,然后在验证这个结论:

dispatchTouchEvent()onInterceptTouchEvent()

  • 返回true表示事件被拦截。不继续。
  • 返回false表示事件不被拦截,继续下一步流程。

onTouchEvent()

  • 返回true表示事件被处理了,不用传递给上一级视图;
  • 返回false表示事件交给上一级视图处理;

初始情况下他们的默认返回值都为false

拦截onInterceptTouchEvent()

如果女班长暗恋帅气的我,自己偷偷帮我完毕了任务,这时候事件就被女班长(MonitressViewGroup)的onInterceptTouchEvent()方法拦截了,即MonitressViewGrouponInterceptTouchEvent()返回ture,此时Log输出例如以下

整理视图例如以下:

相同的,也能够如果老师人比較好,不忍心麻烦学生。自己处理了。这个过程相似女班好处理过程。

到这里,我想大家对事件的分发、拦截已经有一个比較清晰的认识了。接下来我们来看下事件的处理。

处理onTouchEvent()

我们处理完任务后是须要将完毕结果汇报给上级的。也就是帅气的我须要向我亲爱的女班长汇报结果。班长向老师汇报结果。如果我不能按时完毕任务。没将任务结果汇报给女班长。也就是HandsomeMyView的onTouchEvent()方法返回true(事件被处理了。不用返回给上级),此时Log输出例如以下。女班长和老师不用继续处理事件了

整理视图例如以下:

相同的,女班长和老师也能够不像他们各自的上级汇报。过程相似帅气的我(HandsomeMyView)。

Ref

  1. Mastering the Android Touch System
  2. Android群英传

【知识梳理1】Android触摸事件机制的更多相关文章

  1. Android触摸事件传递机制

    简单梳理一下Android触摸事件传递机制的知识点. 一.View与ViewGroup的关系 View和ViewGroup二者的继承关系如下图所示: View是Android中最基本的一种UI组件,它 ...

  2. 初识Android触摸事件传递机制

    前言 今天总结的一个知识点是Andorid中View事件传递机制,也是核心知识点,相信很多开发者在面对这个问题时候会觉得困惑,另外,View的另外一个难题滑动冲突,比如在ScrollView中嵌套Li ...

  3. Android触摸事件的应用

    前言 上一篇讲了Android触摸事件的传递机制,具体可以看这里 初识Android触摸事件传递机制.既然知道Android中触摸事件的传递分发,那么它能解决什么样的问题,在我们实际开发中如何应用,这 ...

  4. Android 触摸事件处理机制

    Android 触摸事件的处理主要涉及到几个方法:onInterceptTouchEvent(), dipatchTouchEvent(), onTouchEvent(), onTouch(). on ...

  5. iOS 和 Android 触摸事件传递

    先看文章,写得很好 ios 触摸事件传递 http://www.cnblogs.com/Quains/p/3369132.html 另外一篇 http://blog.csdn.net/yongyinm ...

  6. 对于android触摸事件模型的一些理解

    body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...

  7. android自定义控件(9)-Android触摸事件分发机制

    触摸事件的传递机制:   首先是最外层的viewgroup接收到事件,然后调用会调用自己的dispatchTouchEvent方法.如果在ACTION_DOWN的时候dispatchTouchEven ...

  8. Android触摸事件传递机制,这一篇就够了

    整个触摸事件牵涉到的是,Activity,View,ViewGroup三者的传递机制. 这个触摸事件就是从外层往内层一层层的传递. 整个传递机制,分为3个步骤:分发,拦截,和消费. 1. 触摸事件的类 ...

  9. 一个demo让你彻底理解Android触摸事件的并发

    注:本文涉及的demo的地址:https://github.com/absfree/TouchDispatch 1. 触摸动作及事件序列 (1)触摸事件的动作 触摸动作一共有三种:ACTION_DOW ...

随机推荐

  1. WEB 前端模块化,读文笔记

    文章链接 WEB 前端模块化都有什么? 知识点 根据平台划分 浏览器 AMD.CMD 存在网络瓶颈,使用异步加载 非浏览器 CommonJS 直接操作 IO,同步加载 浏览器 AMD 依赖前置 req ...

  2. node.js从入门到放弃(一)

    以下内容全是我个人理解写出,如有不对,请立刻练习本人进行更改.以免被刚入门的被我带入坑里. —node是什么?我想大家应该都知道. node是前端未来干掉后端的一种语言,是用JavaScript来编写 ...

  3. UVa-1585-得分

    #include <stdio.h> #include <string.h> int main() { char s[100]; int T; scanf("%d&q ...

  4. java面试微信交流群-欢迎你的加入

    Java后端技术专注Java相关技术:SSM.Spring全家桶.微服务.MySQL.MyCat.集群.分布式.中间件.Linux.网络.多线程,偶尔讲点运维Jenkins.Nexus.Docker. ...

  5. 《算法导论》 — Chapter 8 线性时间排序

    序 到目前为止,关于排序的问题,前面已经介绍了很多,从插入排序.合并排序.堆排序以及快速排序,每一种都有其适用的情况,在时间和空间复杂度上各有优势.它们都有一个相同的特点,以上所有排序的结果序列,各个 ...

  6. webservice学习第二天

    1 课程回顾 l 什么是webservice 远程调用技术:系统和系统之间的调用,获取远程系统里的业务数据 Webservice使用http传输SOAP协议的数据的一种远程调用技术 l Webserv ...

  7. 【ITOO 2】.NET 动态建库建表:使用SQL字符串拼接方式

    导读:在最近接手的项目(高效云平台)中,有一个需求是要当企业用户注册时,给其动态的新建一个库和表.刚开始接手的时候,是一点头绪都没有,然后查了一些资料,也问了问上一版本的师哥师姐,终于有了点头绪.目前 ...

  8. CSU 1307 最短路+二分

    题目大意: 帮忙找到一条a到b的最短路,前提是要保证路上经过的站点的最大距离尽可能短 这道题居然要用到二分...完全没去想过,现在想想求最大距离的最小值确实是... 这里不断二分出值代入spfa()或 ...

  9. Java设计模式之(工厂模式)

    工厂模式: 工厂模式可以分为三类: 1)简单工厂模式(Simple Factory) 2)工厂方法模式(Factory Method) 3)抽象工厂模式(Abstract Factory) 简单工厂模 ...

  10. msp430项目编程22

    msp430中项目---充电控制系统 1.定时器工作原理 2.电路原理说明 3.代码(显示部分) 4.代码(功能实现) 5.项目总结 msp430项目编程 msp430入门学习