Android view 的事件分发机制
1 事件的传递顺序是 Activity -> Window -> 顶层View
touch 事件产生后,最先由 activity 的 dispatchTouchEvent 处理
/**
* Called to process touch screen events. You can override this to
* intercept all touch screen events before they are dispatched to the
* window. Be sure to call this implementation for touch screen events
* that should be handled normally.
*
* @param ev The touch screen event.
*
* @return boolean Return true if this event was consumed.
*/
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
onUserInteraction();
}
if (getWindow().superDispatchTouchEvent(ev)) {
return true;
}
return onTouchEvent(ev);
}
接着事件会传到 Window 的 superDispatchTouchEvent。 如果所有的 view 都没有消费事件,最后会交给 activity 的 onTouchEvent 处理。
2 Window 是一个抽象类,它的唯一实现类是 PhoneWindow
/**
* Abstract base class for a top-level window look and behavior policy. An
* instance of this class should be used as the top-level view added to the
* window manager. It provides standard UI policies such as a background, title
* area, default key processing, etc.
*
* <p>The only existing implementation of this abstract class is
* android.view.PhoneWindow, which you should instantiate when needing a
* Window.
*/
public abstract class Window {
}
查看 PhoneWindow 的 superDispatchTouchEvent
public boolean superDispatchTouchEvent(MotionEvent event) {
return mDecor.superDispatchTouchEvent(event);
}
调用了 mDecor 的 superDispatchTouchEvent
private final class DecorView extends FrameLayout implements RootViewSurfaceTaker {} // This is the top-level view of the window, containing the window decor.
private DecorView mDecor;
mDecor 就是 DecorView, DecorView 是一个 FrameLayout, 就是我们 setContentView 所设置 view 的父容器。
继续看 DecorView 的superDispatchTouchEvent
public boolean superDispatchTouchEvent(MotionEvent event) {
return super.dispatchTouchEvent(event);
}
调用了父类的 dispatchTouchEvent, FrameLayout 中没有 dispatchTouchEvent, 实际上调用了 FrameLayout 的父类 ViewGroup 的 dispatchTouchEvent。
到此事件就传递到了顶层View(ViewGroup) 中,接着事件就从顶层 view 开始向子view分发。
3 事件分发主要涉及 3 个方法
public boolean dispatchTouchEvent(MotionEvent event)
事件传递到一个 view 时就会先调用这个 view 的 dispatchTouchEvent 进行往下分发
public boolean onInterceptTouchEvent(MotionEvent ev)
进行事件的拦截,只有 ViewGroup 有拦截方法, 单一View没有,事件传到 单一View 就直接调用 onTouchEvent 进行处理了
public boolean onTouchEvent(MotionEvent event)
处理事件,true 表示消费这个事件, false 表示不消费
4 下面的伪代码可以很好的说明事件的分发过程
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean consume = false;
if (onInterceptTouchEvent(ev)) {
consume = onTouchEvent(ev);
}else {
consume = child.dispatchTouchEvent(ev);
} return consume;
}
事件传递到顶层 ViewGroup 中后, 就会调用 ViewGroup dispatchTouchEvent 进行分发。如果这个 ViewGroup 的 onInterceptTouchEvent 返回 true 表示它要拦截这个事件,接着就会调用它的 onTouchEvent 进行处理。如果不拦截则会交给它的子 view 继续进行分发, 如此反复直到事件被最终处理。
正常情况下,一个事件序列只能被一个 view 拦截且消耗。一个 view 一旦拦截了某个事件,那么同一个事件序列内的所有的事件都会交给它处理。
如果一个 view 的 onTouchEvent 返回 false, 那么它的父容器的 onTouchEvent 将会被调用,依次类推。如果所有的 view 都不处理这个事件,这个事件最后会返回到 activity 的 onTouchEvent 进行处理。
事件分发具体细节较为复杂,但基本流程就是上面的伪代码。事件分发机制是处理滑动冲突的根本,知道了原理,遇到问题再多看看源码就行了。
Android view 的事件分发机制的更多相关文章
- Android View的事件分发机制
准备了一阵子,一直想写一篇事件分发的文章总结一下.这个知识点实在是太重要了. 一个应用的布局是丰富的,有TextView,ImageView,Button等.这些子View的外层还有ViewGroup ...
- Android View的事件分发机制和滑动冲突解决方案
这篇文章会先讲Android中View的事件分发机制,然后再介绍Android滑动冲突的形成原因并给出解决方案.因水平有限,讲的不会太过深入,只希望各位看了之后对事件分发机制的流程有个大概的概念,并且 ...
- Android View的事件分发机制探索
概述 Android事件传递机制也是Android系统中比较重要的一块,事件类型有很多种,这里主要讨论TouchEvent的事件在framework层的传递处理机制.因为对于App开发人员来说,理解f ...
- Android View 的事件分发原理解析
作为一名 Android 开发者,每天接触最多的就是 View 了.Android View 虽然不是四大组件,但其并不比四大组件的地位低.而 View 的核心知识点事件分发机制则是不少刚入门同学的拦 ...
- 【Android - 自定义View】之View的事件分发机制
参考资料: View事件分发:http://blog.csdn.net/pi9nc/article/details/9281829 ViewGroup事件分发:http://blog.csdn.net ...
- Android中的事件分发机制
Android中的事件分发机制 作者:丁明祥 邮箱:2780087178@qq.com 这篇文章这周之内尽量写完 参考资料: Android事件分发机制完全解析,带你从源码的角度彻底理解(上) And ...
- View的事件分发机制解析
引言 Android事件构成 在Android中,事件主要包含点按.长按.拖拽.滑动等,点按又包含单击和双击,另外还包含单指操作和多指操作.全部这些都构成了Android中的事件响应.总的来说.全部的 ...
- 浅谈Android中的事件分发机制
View事件分发机制的本质就是就是MotionEvent事件的分发过程,即MotionEvent产生后是怎样在View之间传递及处理的. 首先介绍一下什么是MotionEvent.所谓MotionEv ...
- Android中View的事件分发机制
简介 事件也称MotionEvent,事件分发机制就是对MotionEvent事件的分发过程,即当一个MotionEvent发生之后,系统需要把这个事件传递给一个具体的View. 点击事件的分发过程由 ...
随机推荐
- Android 遍历界面控件
//遍历界面上的控件 fubin.pan LinearLayout sLinerLayout = (LinearLayout)findViewById(R.id.layout_scr); for (i ...
- Android音频播放实例
MediaPlayer: 此类适合播放较大文件,此类文件应该存储在SD卡上,而不是在资源文件里,还有此类每次只能播放一个音频文件. 1.从资源文件中播放 MediaPlayer player = ne ...
- django admin 扩展
添加自定义动作: 例子,添加一个方法,批量更新文章,代码如下: from django.contrib import admin from myapp.models import Article de ...
- 【Spring】Spring系列7之Spring整合MVC框架
7.Spring整合MVC框架 7.1.web环境中使用Spring 7.2.整合MVC框架 目标:使用Spring管理MVC的Action.Controller 最佳实践参考:http://www. ...
- jquery check box
if ($("#eulaLine").is(':checked')) { var mobile = $("#mobile").val(); if (mobile ...
- sharepoint添加应用程序
- 【leetcode】Binary Search Tree Iterator
Binary Search Tree Iterator Implement an iterator over a binary search tree (BST). Your iterator wil ...
- python 列表转为字典的两个小方法
1.现在有两个列表,list1 = ['key1','key2','key3']和list2 = ['1','2','3'],把他们转为这样的字典:{'key1':'1','key2':'2','ke ...
- codeforces 489C.Given Length and Sum of Digits... 解题报告
题目链接:http://codeforces.com/problemset/problem/489/C 题目意思:给出 m 和 s,需要构造最大和最小的数.满足长度都为 m,每一位的数字之和等于 s. ...
- 【好用的小技巧】win8兼容、网页不让复制
1.今天下了个matlab7,我用的是win8系统,不兼容. 解决:鼠标右键matlab7的快捷键,点击属性,选择兼容性,选择window vista即可运行 2.在一个 网页上看到一个对自己很有帮助 ...