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. 点击事件的分发过程由 ...
随机推荐
- We are 歪果仁带你灰
We are 歪果仁带你灰 我叫赖彦谕 不爱什么诗和远方 只爱饭桌上的一菜一肉一杯酒 真的很希望有一天我可以成为那个对待学习像对待美食一样的人类 让自己沉浸在美食和知识的海洋中无法自拔 我也对未来的软 ...
- [codeforces 241]C. Mirror Box
[codeforces 241]C. Mirror Box 试题描述 Mirror Box is a name of a popular game in the Iranian National Am ...
- [BZOJ2502]清理雪道
[BZOJ2502]清理雪道 试题描述 滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道),弧的方向代表斜坡下降的方向. 你的团队负责每周定 ...
- 不用任何图片,只用简单的css写出唯美的钟表,就问你行吗?
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAGHCAIAAABJR31QAAAgAElEQVR4nOy9aXhc1ZUurPvcH7f73n ...
- linux文件分割(将大的日志文件分割成小的)
linux文件分割(将大的日志文件分割成小的) linux下文件分割可以通过split命令来实现,可以指定按行数分割和安大小分割两种模式.Linux下文件合并可以通过cat命令来实现,非常简单. 在L ...
- 动态设置Div坐标
<style type="text/css"> #main{text-align:center; background-color:#9FF; height:600px ...
- java类的封装 继承 多态
1.猜数字小游戏 package cn.jiemoxiaodi_02; import java.util.Scanner; /** * 猜数字小游戏 * * @author huli * */ pub ...
- c++ const总结
[本文链接] http://www.cnblogs.com/hellogiser/p/cplusplus-const-summay.html 看到const 关键字,C++程序员首先想到的可能是con ...
- bat批量去除文件首行和合并到文件
bat批量去除文件首行 set n=1 :starline for %%j in (*.txt) do ( :3 if exist D:\work\test\new_%n%.txt (set /a n ...
- php 301
2013年7月1日 13:35:45 PHP在301跳转的时候,如果是跨域跳转,记着把要跳转到的URL添上"http://"