前言

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


废话到此结束。

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

什么是触摸事件

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

  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群英传

转载于:https://www.cnblogs.com/llguanli/p/8515389.html

【知识梳理1】Android触摸事件机制相关推荐

  1. Android 触摸事件机制(三) View中触摸事件详解

    本文将对View中触摸事件相关的内容进行介绍.重点介绍的是dispatchTouchEvent(), onTouchEvent()这两个API以及OnTouchListener接口. 注意:本文是基于 ...

  2. android触摸事件分发,Android 事件分发机制

    Android 事件分发机制一直让人头痛,之前也是面向 GitHub 编程得过且过.今天下定决心了解一下,以便后面自己定制 View 效果.Android 触摸事件有三个基本类型:ACTION_DOW ...

  3. Android 触摸事件处理机制

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

  4. 为了讲清楚Android触摸事件,我“拆了部手机”

    Android 是一个有用户界面(GUI)的操作系统,在它诞生之初,就是为带有触摸屏的手持设备准备的.作为提供给用户最重要的交互方式之一,了解触摸系统是怎么工作的,对于实际的项目开发有着非常大的帮助. ...

  5. Android触摸事件传递分析与实践

    设计UI时,亲爱的交互设计师们总会有一些天马行空的想法,大多数情况下原生的控件已不能支持这些"看似简单"的交互逻辑,需要继承ListView.ViewPager.ScrollVie ...

  6. Android触摸事件实现笔触画布

    任何View都有触摸事件,经常在自定义控件时重写setOnTouchListener 本篇通过手绘图片来讲述这个知识点 本篇分为三个等级:一览图: 直线 曲线 笔触 LEVEL1.png LEVEL2 ...

  7. React Native 手势触摸事件机制详解(进阶篇)

    源码已开源到Github,详细代码可以查看:<React Native 触摸事件代码实践>. 在基础篇,对RN中的触摸事件做了详细的介绍.相信大家对于触摸事件流程机制有了更为清晰的认识.没 ...

  8. Android之Android触摸事件传递机制

    转载请标明出处: http://blog.csdn.net/hai_qing_xu_kong/article/details/53431274 本文出自:[顾林海的博客] ##前言 关于Android ...

  9. android方向触摸事件,Android触摸事件传递机制,这一篇就够了

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

最新文章

  1. pstree进程管理
  2. golang interface 转 string,int,float64
  3. mysql5.7.25源码安装_源码编译安装 mysql5.7.25
  4. vue使用Google Map
  5. svn cvs git的区别
  6. C 语言指针与汇编地址(一)
  7. android预览界面显示不全,Android SurfaceView Camera 预览显示不全(画面拉伸)
  8. 一招搞定让标签title属性值换行
  9. 无法显示jinglingzhoushou-2.0.4.AppImage
  10. python fft函数_python scipy fft.fft用法及代码示例
  11. python获取excel数据制作有文字和图表的报告_Python实现从excel读取数据并绘制成精美图像...
  12. java字节数计算_计算一个Java对象占用字节数的方法
  13. 锂电池保护板测试软件,锂电池保护板测试仪
  14. linux 清除swap 数据,linux清除swap
  15. 如何通过发送短信唤起三方app?
  16. 【转载】uTorrent缓存设置,防止出现磁盘负荷100%
  17. Word邮件合并功能详解:合并后生成多个word文档,删除空白页
  18. python爬虫基础知识
  19. 从Java 9 到 Java 17之Java 11
  20. 【向StoneDB迁移数据】数据迁移同步工具-Gravity

热门文章

  1. Java集合类框架的基本接口有哪些?
  2. VM虚拟机ping不通局域网其他主机的解决办法
  3. ReactNative——打包发布
  4. iOS开发-UIScrollView原理
  5. BrnShop开源网上商城第二讲:ASP.NET MVC框架
  6. winxp精简版没有IIS的解决办法
  7. 排列、组合问题(递归)
  8. python tkinter布局混用_[宜配屋]听图阁
  9. python中文处理
  10. html用a标签怎么提交表单?