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

下面是将ViewdispatchTouchEvent()方法设置断点后,点击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,然后由ActivitydispatchTouchEvent()方法进行事件的分发。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(二)的更多相关文章

  1. Android开发艺术探索笔记—— View(一)

    Android开发艺术探索笔记 --View(一) View的基础知识 什么是View View是Android中所有控件的基类.是一种界面层控件的抽象. View的位置参数 参数名 获取方式 含义 ...

  2. Android开发艺术探索笔记——第一章:Activity的生命周期和启动模式

    Android开发艺术探索笔记--第一章:Activity的生命周期和启动模式 怀着无比崇敬的心情翻开了这本书,路漫漫其修远兮,程序人生,为自己加油! 一.序 作为这本书的第一章,主席还是把Activ ...

  3. Android开发艺术探索笔记之Activity

    内容来源:Android开发艺术探索第一章:Activity的生命周期与启动模式 不能在onPause中做重量级的操作,因为必须执行完成以后新Activity才能Resume.onPause和onSt ...

  4. ViewRoot,DecorView,MeasureSpec和View的工作原理——Android开发艺术探索笔记

    原文链接 http://sparkyuan.me/ 转载请注明出处 View的绘制流程是从ViewRoot的performTraversals方法開始的.它经过measure.layout和draw三 ...

  5. Android中View的事件分发机制——Android开发艺术探索笔记

    原文链接 http://sparkyuan.me/ 转载请注明出处 介绍 点击事件的事件分发就是对MotionEvent事件的分发过程.当一个MotionEvent产生了以后,系统须要把这个事件传递给 ...

  6. 《android开发艺术探索》读书笔记(十二)--Bitmap的加载和Cache

    接上篇<android开发艺术探索>读书笔记(十一)--Android的线程和线程池 No1: 目前比较常用的缓存策略是LruCache和DiskLruCache,LruCache常被用作 ...

  7. 《android开发艺术探索》读书笔记(四)--View工作原理

    接上篇<android开发艺术探索>读书笔记(三) No1: View的三大流程:测量流程.布局流程.绘制流程 No2: ViewRoot对应于ViewRootImpl类,它是连接Wind ...

  8. 《android开发艺术探索》读书笔记(二)--IPC机制

    接上篇<android开发艺术探索>读书笔记(一) No1: 在android中使用多进程只有一种方法,那就是给四大组件在AndroidMenifest中指定android:process ...

  9. 《Android开发艺术探索》读书笔记 (13) 第13章 综合技术、第14章 JNI和NDK编程、第15章 Android性能优化

    第13章 综合技术 13.1 使用CrashHandler来获取应用的Crash信息 (1)应用发生Crash在所难免,但是如何采集crash信息以供后续开发处理这类问题呢?利用Thread类的set ...

随机推荐

  1. django with mysql (part-2)

    step01: write a ( views.py ) file vim views.py Insert the below code : step02: configure your ( urls ...

  2. Leetcode 235 Lowest Common Ancestor of a Binary Search Tree 二叉树

    给定一个二叉搜索树的两个节点,找出他们的最近公共祖先,如, _______6______ / \ ___2__ ___8__ / \ / \ 0 4 7 9 / \ 3 5 2和8的最近公共祖先是6, ...

  3. eclipse code templates 设置(eclipse注释模版配置)

    文件(Files)注释标签:/** * @Title: ${file_name} * @Package ${package_name} * @Description: ${todo} * Copyri ...

  4. hud2544dijkstra+堆优化

    该算法对于稠密图更加有效: 对于给出具有非负权重的边和源顶点S的图G,算法可在O(mlogn)时间内找出从s点到其他每一个顶点的距离. 如果图是稠密的,即对于某个ε>0,m>=n^(1+ε ...

  5. QT on Android开发

    1.安装QT 2.安装JDK 配置如下系统环境变量: JAVA_HOME D:\Java\jdk Path %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin CLASSPATH ...

  6. Clojure上手

    Clojure,这是什么鬼?一门基于JVM(现在也有基于.NET CLR的了:Clojure CLR) 的函数式编程语言.在JVM平台运行的时候,会被编译为JVM的字节码进行运算..为什么要学它?其设 ...

  7. 493萬Gmail用戶的賬號密碼遭洩露,Google否認自己存在安全漏洞

    最近,大公司在互聯網信息安全問題上狀況頻出.上週,蘋果因iCloud被黑客攻擊而導致大量明星私照外洩,著實是熱鬧了一陣.而Google也來湊熱鬧了.據俄羅斯媒體CNews消息,近493萬Gmail用戶 ...

  8. GO語言基礎教程:數組,切片,map

    這節課我們來講解數組,切片和map,或許您是從其他語言轉到GO語言這邊的,那麼在其他語言的影響下您可能會不太適應GO語言的數組,因為GO語言把數組給拆分成了array,slice和map,接下來的時間 ...

  9. 移动APP的IM后台架构浅析

    IM(InstantMessaging 即时通讯)作为一项基础功能,很多APP都有,比如:手机QQ.微信.易信.钉钉.飞信.旺旺.咚咚.陌陌等.而IM如同我们日常生活中的水和电一样,必不可少,也是很多 ...

  10. C#转C++的一点分享

    前几天看到这样一篇博客<那些年·我们读过的专业书籍>,里面列了很多大家认为很好的书,加上自己在自学C++的工程中也看了不少书,感觉并不是所有的书都值得花时间去看的,毕竟很多人一年下来也看不 ...