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)描述了事件对象在 ...
随机推荐
- [Machine Learning with Python] Familiar with Your Data
Here I list some useful functions in Python to get familiar with your data. As an example, we load a ...
- sed实战、find实战、grep实战
1.find实战 # 删除指定文件(三种方法) find /data/ -type f -name "*.log" -exec rm {} \; find /data/ -type ...
- 天天算法————快排及java实现。
快排说的很邪乎,原理懂了,实现自然也就出来了: public void static quickSorted( int[] a ,int low ,int high){ //递归结束条件 if(low ...
- PyTorch学习问题记录
Q1:def train() 中的model.train()的作用是什么?为什么要写? A1:class torch.nn.Module中 train(mode=True) Sets the modu ...
- [Algorithm] Breadth First JavaScript Search Algorithm for Graphs
Breadth first search is a graph search algorithm that starts at one node and visits neighboring node ...
- mysql 导入sql文件时自动切换了大小写
windows环境下: 解决办法(即将其改为大小写敏感): 在my.ini中添加 lower_case_table_names=1
- nodejs 打印机打印 pos打印
https://www.npmjs.com/package/chn-escpos 安装window vsbuild 编译工具 npm install --global --production win ...
- JobConf
/** * A map/reduce job configuration. * 翻译:一个map/reduce作业配置 * <p><code>JobConf</code ...
- 读陈浩的《C语言结构体里的成员数组和指针》总结,零长度数组
原文链接:C语言结构体里的成员数组和指针 复制例如以下: 单看这文章的标题,你可能会认为好像没什么意思.你先别下这个结论,相信这篇文章会对你理解C语言有帮助.这篇文章产生的背景是在微博上,看到@Lar ...
- Allegro16.6和17.0和17.2中将板框导出DXF文件
Allegro16.6和17.0和17.2中将板框导出DXF文件 转载 https://blog.csdn.net/pieces_thinking/article/details/69817600 标 ...