Android Touch消息传递机制探究分析
在Android中,消息的传递控制主要是通过两个方法共同配合使用来对用户的触摸消息进行分发的,下面就来看看这两个方法;
- onInterceptTouchEvent:此方法定义于ViewGroup中,顾名思义,这个方法是用于ViewGroup拦截(intercept)触摸消息的;
- onTouchEvent:此方法定义于View中,用于处理用户的触摸事件;
下面来看这两个方法的定义原型;
public boolean onInterceptTouchEvent(MotionEvent ev);
public boolean onTouchEvent(MotionEvent event);
这两个方法的一个共同点就是都有一个参数MotionEvent用于获取触摸事件的具体信息(比如按下,移动等等消息形态)和函数返回值(用于控制不同场合的触摸处理);
简单说一下MotionEvent,它包含了用户触摸消息的类型,常用的几种触摸消息类型为:ACTION_DOWN,ACTION_MOVE,ACTION_UP,ACTION_CANCEL, 分别表示触摸按下,移动,结束的状态;这几种消息类型不是并发产生的,而是如同触摸发生的次序一样有序产生的,DOWN->MOVE->UP/CANCEL;
下边通过一个例子来研究,分别自定义一个简单的ViewGroup和View,用于跟踪onTouchEvent和onInterceptTouchEvent的执行;
LLinearLayout
public class LLinearLayout extends LinearLayout {
public LLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public LLinearLayout(Context context) {
super(context);
}
private float lastY;
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
String tag = "onInterceptTouchEvent";
Log.w(tag, "" + super.onInterceptTouchEvent(ev));
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.w(tag, "ACTION_DOWN");
lastY = ev.getX();
break;
case MotionEvent.ACTION_MOVE:
Log.w(tag, "ACTION_MOVE");
if (ev.getX() - lastY > 20) {
Log.w(tag, "ACTION_MOVE>20");
return true;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
Log.w(tag, "ACTION_UP");
break;
}
return false;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.w("onTouchEvent", "" + super.onTouchEvent(event));
return false;
}
}
LView
public class LView extends ImageView {
public LView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public LView(Context context) {
super(context);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
String tag = "LView.onTouchEvent";
Log.e(tag, "" + super.onTouchEvent(event));
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.e(tag, "ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
Log.e(tag, "ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
Log.e(tag, "ACTION_UP");
break;
}
return false;
}
}
在xml文件中将LView加入LLinearLayout中,通过一系列更改来一控究竟;
step1:

通过上面的Log信息,可以看出,触摸事件先被LLinearLayout拦截到(onInterceptTouchEvent),在这个Demo中,该方法返回值为false,接着就将Touch事件传递给LView,LView的onTouchEvent响应了此次触摸事件,并且也返回false;然后Touch事件再传递给LLinearLayout的onTouchEvent进行处理;
从上面我们可以简单的看出,Touch事件先被LLinearLayout拦截到,然后传递给LView,LView执行onTouchEvent处理逻辑;然后LLinearLayout再执行自己的onTouchEvent处理逻辑;@1
step2:将上面LLinearLayout的onInterceptTouchEvent方法返回值改为true,再次运行程序;

相比上面的Log信息,可以看到消息没有传递到LView;到这里,应该可以得出一个小小的结论了吧;
ViewGroup里面的onInterceptTouchEvent返回值,返回true表示拦截Touch事件,不再将Touch事件传递给ViewGroup里面的子View;
WVPJ6SJ[D]}DW)9AJNJCP.jpg)
step3: 回到step1,将LView中onTouchEvent返回值改为true,再次运行程序,手指从屏幕右滑到左;

从Log信息中,可以看出,LView的onTouchEvent返回值为true时,LView的触摸事件从DOWN传递到了MOVE,再传递到UP;当然,整个过程都是先由LLinearLayout的onInterceptTouchEvent先接收到Touch事件,在这里,并没有拦截Touch事件,而是将Touch事件传递给子View;细心的朋友可能会发现,在这里,并没有执行到LLinearLayout的onTouchEvent方法,why?其实是因为LView的onTouchEvent事件返回了true,表示处理消耗了此事件,不再继续传递,也就不执行到LLinearLayout的onTouchEvent方法;
结论:View的onTouchEvent返回值表示是否将继续传递Touch事件,比如如果返回true,触摸形态将会从DOWN传递到MOVE再到UP(这里这个说法其实不严谨,这里指的是整个onTouchEvent方法返回值都是true,而没有分段返回,比如在MOVE形态时返回了false);
step4:继续step3,运行程序,手指从屏幕左滑到右;

在LLinearLayout的onInterceptTouchEvent中,如果MOVE消息向右滑动距离大于20,则将拦截Touch事件,所以,在事件被拦截后,将不会再像step3中,MOVE消息会在LView的onTouchEvent中不断传递,而是被中断,触摸形态变为到ACTION_UP即手指抬起(其实这里这样说是不对的,准确的说是触摸形态变为ACTION_CANCEL,因为我将UP和CANCEL处理为一类,所以如上图,打印出来的Log信息为ACTION_UP,实际上它本质是ACTION_CANCEL);然后由于ACTION_MOVE被拦截,所以在手指MOVE的时候LLinearLayout的onTouchEevent不断被调用;
结尾总结:
ViewGroup里的onInterceptTouchEvent默认值是false,只有当返回值是false的时候,Touch事件才传给子View,然后调用到子View的onTouchEvent;返回值为true的时候,将拦截用户Touch事件,子View则捕获不到触摸事件;
View的onTouchEvent方法,当返回值为true的时候,事件将继续往下传递,由ACTION_DOWN传递到ACTION_MOVE再到ACTION_UP,反之如果返回值为false,则只会捕获到MotionEvent的ACTION_DOWN形态;
Android Touch消息传递机制探究分析的更多相关文章
- Android异步消息传递机制源码分析
1.Android异步消息传递机制有以下两个方式:(异步消息传递来解决线程通信问题) handler 和 AsyncTask 2.handler官方解释的用途: 1).定时任务:通过handler.p ...
- Android事件拦截机制简单分析
前一阶段,在学习的时候,遇到了我觉得的我接触安卓以来的最多的一次事件拦截出来,那个项目,用到了slidemenu側滑菜单条,然后加上tab标签,还有轮播广告,listview上下滑动.viewpage ...
- 解析Android的 消息传递机制Handler
1. 什么是Handler: Handler 网络释义"机械手.经理"意思,在Android它用于管理多个线程UI操作: 2. 为什么会出现Handler: 在Android里面的 ...
- Android touch mode和focusableInTouchMode分析
首先我们来看看touch mode的定义.它是用户和手机进行交互时view层次结构的一个状态.它本身是很容易理解的, 代表了最近一次的交互是否是通过触摸屏发生的,因为在Android设备上还存在别的交 ...
- Android事件分发机制源代码分析
小小感慨一下,做android有一段时间了,一直以来都是习惯整理笔记存到有道笔记上,没有写博客的习惯. 以后逐步分类整理出来,也算"复习"一遍了 - _ - . android的事 ...
- Android Handler消息传递机制
在Android系统中,类Handler主要有如下两个作用. 在新启动的线程中发送消息. 在主线程中获取.处理消息. 类Handler在实现上述作用时,首先在新启动的线程中发送消息,然后在主线程中获取 ...
- Android学习笔记-事件处理之Handler消息传递机制
内容摘要:Android Handler消息传递机制的学习总结.问题记录 Handler消息传递机制的目的: 1.实现线程间通信(如:Android平台只允许主线程(UI线程)修改Activity里的 ...
- Android事件传递机制详解及最新源码分析——ViewGroup篇
版权声明:本文出自汪磊的博客,转载请务必注明出处. 在上一篇<Android事件传递机制详解及最新源码分析--View篇>中,详细讲解了View事件的传递机制,没掌握或者掌握不扎实的小伙伴 ...
- Android Touch事件传递机制 二:单纯的(伪生命周期)
转载于:http://blog.csdn.net/yuanzeyao/article/details/38025165 在前一篇文章中,我主要讲解了Android源码中的Touch事件的传递过程,现在 ...
随机推荐
- [WinAPI] API 5 [遍历驱动器并获取驱动器属性]
(1) GetLogicalDrives.获取主机中所有的逻辑驱动器,以BitMap的形式返回.◇返回值GetLogicalDrive函数返回一个DWORD类型的值,第一位表示所对应的驱动器是否存在. ...
- JPA 使用
本文以JPA+Hibernate 角色与权限示例说明. 角色实体定义: @Entity @Table public class Role { private long id; private Stri ...
- 布局神器display:table-cell
元素两端对齐 第一个案例是让两个元素分别向左和向右对齐,如果是过去,我一定会用float来实现,但其实用table可以这么做: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...
- javaweb学习总结(四)——Http协议
一.什么是HTTP协议 HTTP是hypertext transfer protocol(超文本传输协议)的简写,它是TCP/IP协议的一个应用层协议,用于定义WEB浏览器与WEB服务器之间交换数据的 ...
- Python面试题(一)
**晚上在公司的论坛上看到一道面试题,题目如下:随机给定一字符串和字符,要求重排,比如:'abde','c'.重排之后变成'abcde' **看到他们给的答案很多都是二分法重排,既然是字符类的处理,当 ...
- Django简介
Django, 应该读作jan go,读音演示 D是不发音的---发音的---音的---的--- django简介:urls.py网址入口,关联到views.py views.py处理用户发出的请求, ...
- SAP Business One SAP B1功能概述
SAP Business One SAP B1功能概述 SAP B One配有易于使用的软件界面,是一款全面的,多功能的业务管理解决方案,贵企业可以将其用作主要的企业资源(ERP)应用程序. 该解决方 ...
- Android的消息机制: Message/MessageQueue/Handler/Looper
概览 * Message:消息.消息里面可包含简单数据.Object和Bundle,还可以包含一个Runnable(实际上可看做回调). * MessageQueue:消息队列,供Looper线程 ...
- 【转】webstorm 注册码 / phpstorm 注册码
WebStorm注册码 User Name: EMBRACE License Key: ===== LICENSE BEGIN ===== 24718-12042010 00001h6wzKLpfo3 ...
- Huxley 是一个用于Web应用 UI 测试的工具
Huxley 是一个用于Web应用 UI 测试的工具,由 Pete Hunt 和 Maykel Loomans 用 Python 开发. UI 测试比较令人头疼. UI测试不好写,而且很容易失效: ...