Android -- TouchEvent的分发和截获方式
Android系统中的每个ViewGroup的子类都具有下面三个和TouchEvent处理密切相关的方法:
public boolean dispatchTouchEvent(MotionEvent ev) // 这个方法用来分发TouchEvent public boolean onInterceptTouchEvent(MotionEvent ev) //这个方法用来拦截TouchEvent public boolean onTouchEvent(MotionEvent ev) //这个方法用来处理TouchEvent
注意:不是所有的View的子类,很多教程都说的是所有的View的子类,只有可以向里面添加View的控件才需要分发,比如TextView它本身就是最小的view了,所以不用再向它的子视图分发了,它也没有子视图了,所以它没有dispatch和Intercept,只有touchEvent。
onInterceptTouchEvent(MotionEvent ev)方法是GroupView控件中特有的一个方法,我们可以实现这个方法来截获所有的窗口点击事件来根据事件的不同来对子控件或自身分发事件触发。覆盖这个方法时需要小心注意,因为它和View.onTouchEvent(MotionEvent)有着复杂的关系,我们使用是需要和View.onTouchEvent(MotionEvent)一同实现来达到正确的结果,事件触发顺序如下:
1.你首先会在该方法中得到一个down事件。
2.这个down事件会被得到处理,要么在这个GroupView中子控件的onTouchEvent()方法中,要么在GroupView自身的onTouchEvent()方法中。当我们在onTouchEvent()方法返回值中返回true的话,将会继续看到后续的触发事件(move、up等),要注意的是当我们在GroupView的onTouchEvent()事件返回值中返回false的话,该方法将不再捕获后续的(move up)事件。
3.如果在该方法返回值中返回false,down事件将根据控件树结构从根节点向目标子控件的onTouchEvent()方法分发。
4.如果在该方法返回值中返回true,那么你的子控件将获取不到任何点击事件。
为证明上面所说的顺序特点,下面通过测试代码来观察观察:
public class MainActivity extends Activity {
Group1 group1;
Group2 group2;
MyTextView myTv;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//--group1
//----|
//-------group2
//---------|
//------------myTv
group1 = new Group1(this);
group2 = new Group2(this);
myTv = new MyTextView(this);
group2.addView(myTv, new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
group1.addView(group2, new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
setContentView(group1);
}
}
分别重写Group1和Group2的onInterceptTouchEvent和onTouchEvent方法,重写MyTextView的onTouchEvent方法,最终得到的控件层次结构如下:

1.在默认返回值情况下logcat输出如下:

测试后可知默认情况下和所有方法返回值为false的结果一致,down事件的捕获顺序onInterceptTouchEvent先于onTouchEvent,由于onTouchEvent返回值为false,down事件没被消化,后续的move和up事件没有出现,同时逆序返回到父控件的onTouchEvent方法来捕获,如下图所示:

2.所有onTouchEvent返回值为true情况下logcat输出如下:

输出结果可以看出子控件MyTextView消化了down事件,后续的move和up事件正常捕获,由于down事件被消化,上层的onTouchEvent方法不执行,如下图所示:(三箭头分别指down、move、up事件)

既然如此,如果MyTextView中onTouchEvent方法返回为false,而group1和group2的onTouchEvent方法返回true的结果自然也就如下图的顺序了:

测试输出结果证明了这一猜测顺序,

3.当某个GroupView中的onInterceptTouchEvent方法返回值为true情况下logcat输出如下(如group2):

如果在该方法返回值中返回true,那么子控件将获取不到任何点击事件,转而向自身的onTouchEvent方法转发,如下图所示:

如果onTouchEvent方法返回值都为true,那么根据规律结果就如下图顺序触发:

最后logcat的结果证实了这一猜测,

根据这一顺序规律我们便可复写GroupView中的onInterceptTouchEvent来控制事件的响应者。
我是天王盖地虎的分割线
参考:http://blog.csdn.net/alexander_xfl/article/details/11056679
Android -- TouchEvent的分发和截获方式的更多相关文章
- 一文读懂 Android TouchEvent 事件分发、拦截、处理过程
什么是事件?事件是用户触摸手机屏幕,引起的一系列TouchEvent,包括ACTION_DOWN.ACTION_MOVE.ACTION_UP.ACTION_CANCEL等,这些action组合后变成点 ...
- Android Touch事件分发过程
虽然网络上已经有非常多关于这个话题的优秀文章了,但还是写了这篇文章,主要还是为了加强自己的记忆吧,自己过一遍总比看别人的分析要深刻得多.那就走起吧. 简单演示样例 先看一个演示样例 : 布局文件 : ...
- 国内Android应用推广的六大主流方式
国内Android应用推广的六大主流方式 http://mobi.baike.com/article-19433.html 随着Android市场份额的飞速增长,越来越多的国内开发团队和公司開始投入A ...
- Android事件总线分发库EventBus3.0的简单讲解与实践
Android事件总线分发库EventBus的简单讲解与实践 导语,EventBus大家应该不陌生,EventBus是一款针对Android优化的发布/订阅事件总线.主要功能是替代Intent,Han ...
- Android的事件分发
1. Touch事件和绘制事件的异同之处 Touch事件和绘制事件非常相似,都是由ViewRoot派发下来的,可是不同之处在绘制事件是由应用中的某个View发起请求,一层一层上传到ViewRoot.再 ...
- Android View 事件分发机制 源码解析 (上)
一直想写事件分发机制的文章,不管咋样,也得自己研究下事件分发的源码,写出心得~ 首先我们先写个简单的例子来测试View的事件转发的流程~ 1.案例 为了更好的研究View的事件转发,我们自定以一个My ...
- Android数据的四种存储方式SharedPreferences、SQLite、Content Provider和File (一) —— 总览
Android数据的四种存储方式SharedPreferences.SQLite.Content Provider和File (一) —— 总览 作为一个完成的应用程序,数据存储操作是必不可少的. ...
- Android网络之数据解析----SAX方式解析XML数据
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...
- Android之事件分发机制
本文主要包括以下内容 view的事件分发 viewGroup的事件分发 首先来看两张图 在执行touch事件时 首先执行dispatchTouchEvent方法,执行事件分发. 再执行onInterc ...
随机推荐
- SQL 2008配置管理工具服务显示 远程过程调用失败0x800706be
摘自: http://www.cnblogs.com/cool-fire/archive/2012/09/15/2686131.html 基本上我的解决方案也是根据该文提示 操作的. 因为 我后来 装 ...
- 会"说话"的勒索病毒Cerber
最近有个案子与勒索病毒有关,证物是个台式机,运行Windows 7 64bit操作系统,委托方是某高科技公司,希望能调查出事发的关键时间点.感染来源及途径.恶意程序文件名等相关信息. 在对证物计算机进 ...
- 十四、Struts2的国际化
十四.Struts2的国际化 1.配置全局国际化消息资源包 配置全局消息资源包 <!--配置全局消息资源包 --> <constant name="struts.c ...
- 实现支持在Mac OS的最小大化的过渡效果
实现支持在Mac OS的最小大化的过渡效果,该源码是刚刚在源码天堂那个网站上转载过来的,个人感觉还不错的,大家可以学习一下吧. 源码下载:http://code.662p.com/view/2250. ...
- 阿里云利用web直传文件到oss服务器
http://files.cnblogs.com/files/adtuu/oss-h5-upload-js-direct.tar.gz
- activity切换动画特效
效果图: 结构图: 测试代码: 布局: <?xml version="1.0" encoding="utf-8"?> <LinearLayou ...
- 重命名Oracle数据库的表空间(Renaming a Tablespace)
重命名一个表空间时,Oracle会在数据字典.控制文件和数据文件的头部更新这个表空间名. 注意,重命名一个表空间不会重命名相关联的数据文件. 重命名代码示例如下: SQL> alter tabl ...
- opengl基础学习专题 (三) 多边形绘制的几种样式
题外话 聪明人之所以不会成功,是由于他们缺乏坚韧的毅力. ——艾萨克·牛顿(1643年1月4日—1727年3月31日)英国 也许可以理解为 想更深一步的时候,坚持,努力和聪明缺一不可. 挺直腰杆在此向 ...
- MIFARE系列4《组成图》
MIFARE集成电路芯片内含EEPROM.RF接口和数字控制单元. 1. RF射频接口 在RF射频接口电路中,主要包括有波形转换模块.它可将卡片读写器上的13.56MHZ的无线电调制频率接收,一方面送 ...
- Python数据类型-----数字&字符串
Python数字类型 int类型表示的范围:-2147483648至2147483648之间,超出这个范围的数字即视为long(长整形) 在Python中不需要事先声明数据类型,它是根据具体的赋值来进 ...