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 ...
随机推荐
- WeChat 6.3 wipe deleted chat messages as well as LINE 5.3 and above
Let me show you the WeChat version first. It is 6.3. What will happen to WeChat deleted chat message ...
- hdu1505
the main algorithm as the 1506 #include <stdio.h> #include <iostream> #include <strin ...
- xdotool-linux下的按键精灵
这是我在ST写的用来自动打开机顶盒的脚本 #!/bin/bash init_stb() { xdotool type "telnet 10.80.117.$1" xdotool k ...
- vs2008 连接 VSS不提示输入密码
之前使用的vs2005,每次登录的时候会有vss帐号输入框,如上图. 后来安装了vs2008,再打开源代码的时候输入框就不见了,下面是解决办法. --------------------------- ...
- 如何添加localizable.strings本地化
1.在Supporting Files文件夹右键,NewFile… -> iOS -> Resources -> String Files,命名为Localizable.string ...
- CentOS学习笔记--文件权限概念
Linux 文件权限概念 当你的屏幕出现了『Permission deny』的时候,不要担心,『肯定是权限设定错误』啦!(以下节选自 鸟哥的 Linux 私房菜 第六章.Linux 的文件权限与目录配 ...
- Objective-C数据类型、数据类型转换
数据类型 1.Objective-C数据类型可以分为:基本数据类型.对象数据类型和id类型. 2.基本数据类型有:int.float.double和char类型. 3.对象类型就是类或协议所声明的指针 ...
- Nginx Location配置语法介绍、优先级说明
nginx 语法规则:location [=|~|~*|^~|!~|!~*] /uri/ { … } location匹配的是$document_uri,$document_uri 会随 ...
- apache下ab.exe使用方法。。
自己在cmd中写了半天的路径也没有写对..最后网上的一个哥们告诉我说没有共同语言了...毛线啊 差距确实很大!大能猫死panda早晚干掉你,叫你丫整天嘲讽我! 比如我的ab.exe在D盘的wamp文件 ...
- String类的比较
//strcmp只能运用于数组的比较 //string类可以用成员函数compare() //即a.compare(b) //例如 "; "; a.compare(b)返回值= & ...