Anroid事件分发
因为最近因个人原因离职,面试的时候,有人问到了Android中事件分发机制的过程,因为忘得差不多了,没答好,所以回来后,想写了个Demo,重新复习一遍。
一般来说,Android的组件其实可以分为两类,即View和ViewGroup,而ViewGroup又继承于View。对于ViewGroup的是事件分发主要涉及到三个方法:
dispatchTouchEvent(MotionEvent ev),onInterceptTouchEvent(MotionEvent ev)和onTouchEvent(MotionEvent event),而View主要涉及到
dispatchTouchEvent(MotionEvent ev)和onTouchEvent(MotionEvent event)。顾名思义,dispatchTouchEvent用于分发Touch事件,
onInterceptTouchEvent用于拦截Touch事件,而onTouchEvent则是用于处理Touc事件。
首先,我们写一个简单的Demo来看看,
public class MyLinearLayout extends LinearLayout {
public MyLinearLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public MyLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyLinearLayout(Context context) {
super(context);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.d("test", "MyLinearLayout"+" dispatchTouchEvent");
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.d("test", "MyLinearLayout"+" onInterceptTouchEvent");
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.d("test", "MyLinearLayout"+" onTouchEvent");
return super.onTouchEvent(event);
}
}
public class MyView extends TextView {
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyView(Context context) {
super(context);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
Log.d("test", "MyView"+" dispatchTouchEvent");
return super.dispatchTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.d("test", "MyView"+" onTouchEvent");
return super.onTouchEvent(event);
}
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.eventdemo.MainActivity" > <com.example.test1.MyLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<com.example.test1.MyView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="00000000000000000000"
/> </com.example.test1.MyLinearLayout> </RelativeLayout>
上面我主要定义了一个ViewGroup(MyLinearLayout)和一个View(MyView),然后分别打印出dispatchTouchEvent(MotionEvent ev),onInterceptTouchEvent(MotionEvent ev)和onTouchEvent(MotionEvent event)的Log:

通过上面的Log可以看出,ViewGroup和View中的事件默认分发顺序是:ViewGruop.dispatchTouchEvent --> ViewGruop.onInterceptTouchEvent
--> View.dispatchTouchEvent --> View.onTouchEvent --> ViewGroup.onTouchEvent.
那如果我们对View的onTouchEvent事件的返回值修改下,会变成什么样呢?
首先,我将MyView中的onTouchEvent方法中直接return true,然后看下Log:

可以发现,MyLinearLayout的onTouchEvent没有执行,这是因为这次Touch事件已经被MyView消费了,即如果我们在方法中直接return true,那么事件就不会继续分发下去了。
接着,我们在MyLinearLayout的dispatchTouchEvent方法中return true,然后看Log:
总结如下:
- dispatchTouchEvent返回true,意味后续不会将事件进行分发,而是直接在dispatchTouchEvent中进行拦截,即后续的ACTION_MOVE,ACTION_UP,ACTION_CANCEL事件只会触发ViewGroup和ViewGroup之前路径的View以及ViewGroup(需要注意的是,如果是在onTouch中,返回true,则下次的ACTION_DOWN,ACTION_UP就只会触发该ViewGroup的onTouch事件,即系统是会记住消费了onTouch事件的那个ViewGroup来传递事件)的dispatchTouchEvent和onInterceptTouchEvent
,而不会触发ViewGroup以及ViewGroup之后的View的onInterceptTouchEvent()和onTouchEvent()事件. - dispatchTouchEvent返回返回false,意味着不处理该事件,也不往下分发事件。即后续不会收到ACTION_MOVE,ACTION_UP,ACTION_CANCEL事件.
- 返回super.dispatchTouchEvent(ev)意味着不处理该事件,而是依次向子View分发该事件,直到找到需要消费本次事件的View.
所以如果我们需要将事件拦截下来的话,直接return true就可以了。
Anroid事件分发的更多相关文章
- C++中的事件分发
本文意在展现一个C++实现的通用事件分发系统,能够灵活的处理各种事件.对于事件处理函数的注册,希望既能注册到普通函数,注册到事件处理类,也能注册到任意类的成员函数.这样在游戏客户端的逻辑处理中,可以非 ...
- Android事件分发机制浅谈(一)
---恢复内容开始--- 一.是什么 我们首先要了解什么是事件分发,通俗的讲就是,当一个触摸事件发生的时候,从一个窗口到一个视图,再到一个视图,直至被消费的过程. 二.做什么 在深入学习android ...
- 简单例子了解View的事件分发
什么是事件分发 我们在写自定义ViewGroup或者自定义View的时候经常要处理用户的点击事件,如果我们的View在最底层,他在很多ViewGroup里面,我们如何让我们的点击事件准确传递到View ...
- Android事件分发机制浅谈(二)--源码分析(ViewGroup篇)
上节我们大致了解了事件分发机制的内容,大概流程,这一节来分析下事件分发的源代码. 我们先来分析ViewGroup中dispatchTouchEvent()中的源码 public boolean dis ...
- 通俗理解Android事件分发与消费机制
深入:Android Touch事件传递机制全面解析(从WMS到View树) 通俗理解Android事件分发与消费机制 说起Android滑动冲突,是个很常见的场景,比如SliddingMenu与Li ...
- EventDispatcher 事件分发组件
引言 考虑这样一个问题,现在你想给为你的项目提供一个插件系统,插件可以添加一些方法,或者在某些方法执行之前或者之后做些事情,而不干扰其他插件.要实现这个系统,简单的单继承不是个好办法,即使多继承在PH ...
- Android事件分发小结
******** ******** 第一部分: 介绍说明 ******** ******** 个人感觉在做交互的时候, 对于Android的按键分发的理解还是比较重要的. 这些内容在 ...
- Atitit View事件分发机制
1. Atitit View事件分发机制 1. Atitit View事件分发机制1 1.1. 三个关键方法 dispatchTouchEvent onInterceptTouchEvent onTo ...
- [DOM Event Learning] Section 4 事件分发和DOM事件流
[DOM Event Learning] Section 4 事件分发和DOM事件流 事件分发机制: event dispatch mechanism. 事件流(event flow)描述了事件对象在 ...
随机推荐
- idea没有subversion问题
问题描述:idea导入svn项目,但点击项目文件右键没有找到subversion选项.同时,idea界面底部没有version control菜单. 解决方法:原因是idea没有启动版本控制.点击id ...
- BZOJ1013球形空间产生器sphere 高斯消元
@[高斯消元] Description 有一个球形空间产生器能够在n维空间中产生一个坚硬的球体.现在,你被困在了这个n维球体中,你只知道球 面上n+1个点的坐标,你需要以最快的速度确定这个n维球体的球 ...
- Jena+fuseki
1.下载apache-jena-3.1.0.tar.gz,这个可以将ttl三元组文件或者xml文件加载 进入bin目录,执行./tdbloader2 --loc /path/for/database ...
- MFC改变控件颜色
from http://www.cppblog.com/FandyM/archive/2010/07/21/120972.aspx MFC应用程序中,要改变控件的背景色可通过重载OnCtlColor( ...
- 产品如何进行大屏数据可视化.md
最近接到一个需求,需要给公司的竞赛平台面对省/校/竞赛进行大屏的可视化话数据展示,闲暇之余对自己最近的工作进行一些总结; 一.数据可视化的定义 数据可视化主要是关于数据_视觉表现形式的科学技术研究 - ...
- 【层次查询】Hierarchical Queries之亲兄弟间的排序(ORDER SIBLINGS BY)
http://blog.itpub.net/519536/viewspace-624176 有关层次查询之前的文章参考如下. [层次查询]Hierarchical Queries之"树的遍历 ...
- HDU 5289 Assignment(单调队列)
题意:给T足数据,然后每组一个n和k,表示n个数,k表示最大同意的能力差,接下来n个数表示n个人的能力,求能力差在k之内的区间有几个 分析:维护一个区间的最大值和最小值,使得他们的差小于k,于是採用单 ...
- Eclipse 教程
Eclipse 教程 Eclipse 是一个开放源代码的.基于 Java 的可扩展开发平台. Eclipse 是 Java 的集成开发环境(IDE),当然 Eclipse 也可以作为其他开发语言的集成 ...
- Web文件的ContentType类型大全
".*"="application/octet-stream"".001"="application/x-001"&qu ...
- 转:学习linux驱动经典书籍
Linux驱动学习的最大困惑在于书籍的缺乏,市面上最常见的书为<linux_device_driver 3rd Edition>,这是一本很经典的书,无奈Linux的东东还是过于庞大,这本 ...