Android开发艺术探索笔记——View(二)
Android开发艺术探索笔记——View(二)
View的事件分发机制
学习资料:
1.Understanding Android Input Touch Events System Framework
2.Managing Touch Events in a ViewGroup
3.Android事件传递机制
4.Input Events
5.Mastering the Android Touch System
6.MotionEvent
MotionEvent(运动事件)的传递规则
用户每次触摸屏幕都被包装成了MotionEvent(运动事件)对象。
属性有:
- 动作码(action code),如
ACTION_DOWN,ACTION_UP等等,用于描述用户当前的动作。 - 触摸的横纵坐标。
- 其它信息,如压力,大小以及方向等等。
View的事件分发,就是对MotionEvent事件的分发过程。
事件分发的三个重要方法:
//用于分发事件(dispatch touch event),要么将事件向下传递到目标View,要么交由自己处理。
//返回true表示自己处理
public boolean dispatchTouchEvent (MotionEvent event)
//用于拦截事件(intercept touch event),ViewGroup中有,View中没有这个方法。
public boolean onInterceptTouchEvent (MotionEvent event)
//用于处理事件
public boolean onTouchEvent (MotionEvent event)
三个方法的关系可用如下伪代码描述:
public boolean dispatchTouchEvent(MotionEvent ev){
boolean consume = false;
if(onInterceptTouchEvent(ev)){
consume = true;
}else{
consume = child.dispatchTouchEvent(ev);
}
return consume;
}

View的onTouchListener的优先级比onTouchEvent方法的高。
运动事件的传递顺序:
Activity-->Window-->View
下面是将View的dispatchTouchEvent()方法设置断点后,点击ImageView的调试过程:

能清楚地看到事件的传递过程和顺序。
若View的onTouchEvent()方法返回false,则会调用它的父View的onTouchEvent()方法,依此类推,若调用顺序上的所有View都不处理这个事件,则这个事件会最终传递给Activity的onTouchEvent()方法。
View的事件分发机制类似于互联网公司的工作流程:
新任务:
CEO-->产品经理-->CTO-->开发小组组长-->程序员
由上至下一级一级分发任务(dispatchTouchEvent),如果是自己的任务(onInterceptTouchEvent)
,则拦截自己处理(onTouchEvent),反之,则交由下级分发(child.dispatchTouchEvent)。
如果事情搞不定,就一级一级向上抛(parent.onTouchEvent):
程序员-->开发组长-->CTO-->产品经理-->CEO
事件传递机制的一些结论:
- 1.事件序列:从手指接触屏幕到手指离开屏幕的过程,ACTION_DOWN-->ACTION_MOVE-->...-->ACTION_MOVE-->ACTION_UP
- 2.一个事件序列只能被一个View拦截且消费。
- 3.ViewGroup默认不拦截事件。源码中ViewGroup的
onInterceptTouchEvent()方法默认返回false - 4.View没有
onInterceptTouchEvent()方法 - 5.事件传递是由外向内(由上至下)的。事件先传递给父元素,然后再由父元素分发给子元素。通过
requestDisallowInterceptTouchEvent()方法可以在子元素中干预父元素的事件分发过程。
事件分发源码解析
Activity对事件的分发过程
- 1.点击事件首先传递给
Activity,然后由Activity的dispatchTouchEvent()方法进行事件的分发。Activity会将事件交由window进行分发。
//Activity源码
...
/*
* Activity的dispatchTouchEvent方法
*/
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
onUserInteraction();
}
//Activity交由window进行事件分发
if (getWindow().superDispatchTouchEvent(ev)) {
return true;
}
return onTouchEvent(ev);
}
- 2.Window将事件传递给DecorView(即ContentView的父View,可通过
Activity.getWindow().getDecorView()方法获取)。而Window类是抽象类,superDispatchTouchEvent()方法是抽象方法。
//Window类是抽象类
public abstract class Window {
...
//window的superDispatchTouchEvent方法是抽象方法
public abstract boolean superDispatchTouchEvent(MotionEvent event);
...
}
而PhoneWindow类是Window类的唯一实现类。
public class PhoneWindow extends Window implements MenuBuilder.Callback {
...
@Override
public boolean superDispatchTouchEvent(MotionEvent event) {
//PhoneWindow直接将事件交友DecorView处理
return mDecor.superDispatchTouchEvent(event);
}
...
}
可以看到PhoneWindow类在实现抽象方法superDispatchTouchEvent时,直接将事件交由DecorView处理。
Android开发艺术探索笔记——View(二)的更多相关文章
- Android开发艺术探索笔记—— View(一)
Android开发艺术探索笔记 --View(一) View的基础知识 什么是View View是Android中所有控件的基类.是一种界面层控件的抽象. View的位置参数 参数名 获取方式 含义 ...
- Android开发艺术探索笔记——第一章:Activity的生命周期和启动模式
Android开发艺术探索笔记--第一章:Activity的生命周期和启动模式 怀着无比崇敬的心情翻开了这本书,路漫漫其修远兮,程序人生,为自己加油! 一.序 作为这本书的第一章,主席还是把Activ ...
- Android开发艺术探索笔记之Activity
内容来源:Android开发艺术探索第一章:Activity的生命周期与启动模式 不能在onPause中做重量级的操作,因为必须执行完成以后新Activity才能Resume.onPause和onSt ...
- ViewRoot,DecorView,MeasureSpec和View的工作原理——Android开发艺术探索笔记
原文链接 http://sparkyuan.me/ 转载请注明出处 View的绘制流程是从ViewRoot的performTraversals方法開始的.它经过measure.layout和draw三 ...
- Android中View的事件分发机制——Android开发艺术探索笔记
原文链接 http://sparkyuan.me/ 转载请注明出处 介绍 点击事件的事件分发就是对MotionEvent事件的分发过程.当一个MotionEvent产生了以后,系统须要把这个事件传递给 ...
- 《android开发艺术探索》读书笔记(十二)--Bitmap的加载和Cache
接上篇<android开发艺术探索>读书笔记(十一)--Android的线程和线程池 No1: 目前比较常用的缓存策略是LruCache和DiskLruCache,LruCache常被用作 ...
- 《android开发艺术探索》读书笔记(四)--View工作原理
接上篇<android开发艺术探索>读书笔记(三) No1: View的三大流程:测量流程.布局流程.绘制流程 No2: ViewRoot对应于ViewRootImpl类,它是连接Wind ...
- 《android开发艺术探索》读书笔记(二)--IPC机制
接上篇<android开发艺术探索>读书笔记(一) No1: 在android中使用多进程只有一种方法,那就是给四大组件在AndroidMenifest中指定android:process ...
- 《Android开发艺术探索》读书笔记 (13) 第13章 综合技术、第14章 JNI和NDK编程、第15章 Android性能优化
第13章 综合技术 13.1 使用CrashHandler来获取应用的Crash信息 (1)应用发生Crash在所难免,但是如何采集crash信息以供后续开发处理这类问题呢?利用Thread类的set ...
随机推荐
- OpenWrt资料汇总
上周末折腾了一下OpenWrt,打算把Facebook的网络模拟工具部署到上面,最终以失败告终.上github看,发现已经有人给作者提了issue,作者表示部署在OpenWrt上会很有用,但确实在Op ...
- dns简介
dns(domain name system),它是提供域名到ip的解析功能的系统.它和普通的系统一样,也是运行在服务器之上的. 1.dns指定的ip是用来干嘛的? 这个ip指向dns系统所在的机器. ...
- atitit.人脸识别的应用场景and使用最佳实践 java .net php
atitit.人脸识别的应用场景and使用最佳实践 java .net php 1. 人脸识别的应用场景 1 2. 框架选型 JNI2OpenCV.dll and JavaCV 1 3. Url ap ...
- atitit.信息安全的控制总结o7
atitit.信息安全的控制总结o7 1. 信息安全覆盖很多的内容: 1 2. #内部人员导致的安全风险 1 3. #对敏感的数据进行透明的加密 2 4. #安全防护 2 5. #通过数据安全域保护关 ...
- paip.php 5.0 5.3 5.4 5.5 -6.0的新特性总结与比较
paip.php 5.0 5.3 5.4 5.5 -6.0的新特性总结与比较 PHP5的新特性 2 · 对象的参照过渡是默认的(default) 3 · 引入访问属性的限制 3 · 引入访问方法的限 ...
- Leetcode 303 Range Sum Query - Immutable
题意:查询一个数组在(i,j]范围内的元素的和. 思路非常简单,做个预处理,打个表就好 拓展:可以使用树状数组来完成该统计,算法复杂度为(logn),该数据结构强力的地方是实现简单,而且能完成实时更新 ...
- Struts2入门1 Struts2基础知识
Struts2入门1 Struts2基础知识 20131130 代码下载: 链接: http://pan.baidu.com/s/11mYG1 密码: aua5 前言: 之前学习了Spring和Hib ...
- iOS开发实用技巧—项目新特性页面的处理
iOS开发实用技巧篇—项目新特性页面的处理 说明:本文主要说明在项目开发中会涉及到的最最简单的新特性界面(实用UIScrollView展示多张图片的轮播)的处理. 代码示例: 新建一个专门的处理新特性 ...
- asp.net 读取RedisSessionStateProvider配置
最近项目遇到需要读取RedisSessionStateProvider配置文件applicationName节点,如: 读取的方法有很多: 1直接读取web.config文件, void test1( ...
- Android基本功:手势
一.概念 手势:其实是指用户手指或触摸笔在屏幕上的连续触碰行为,Andoird对两种手势行为都提供了支持: Andorid提供了手势检测,并为手势检测提供了相应的监听器: Android允许开发者添加 ...