在Android中,消息的传递控制主要是通过两个方法共同配合使用来对用户的触摸消息进行分发的,下面就来看看这两个方法;

  1. onInterceptTouchEvent:此方法定义于ViewGroup中,顾名思义,这个方法是用于ViewGroup拦截(intercept)触摸消息的;
  2. 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;

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消息传递机制探究分析的更多相关文章

  1. Android异步消息传递机制源码分析

    1.Android异步消息传递机制有以下两个方式:(异步消息传递来解决线程通信问题) handler 和 AsyncTask 2.handler官方解释的用途: 1).定时任务:通过handler.p ...

  2. Android事件拦截机制简单分析

    前一阶段,在学习的时候,遇到了我觉得的我接触安卓以来的最多的一次事件拦截出来,那个项目,用到了slidemenu側滑菜单条,然后加上tab标签,还有轮播广告,listview上下滑动.viewpage ...

  3. 解析Android的 消息传递机制Handler

    1. 什么是Handler: Handler 网络释义"机械手.经理"意思,在Android它用于管理多个线程UI操作: 2. 为什么会出现Handler: 在Android里面的 ...

  4. Android touch mode和focusableInTouchMode分析

    首先我们来看看touch mode的定义.它是用户和手机进行交互时view层次结构的一个状态.它本身是很容易理解的, 代表了最近一次的交互是否是通过触摸屏发生的,因为在Android设备上还存在别的交 ...

  5. Android事件分发机制源代码分析

    小小感慨一下,做android有一段时间了,一直以来都是习惯整理笔记存到有道笔记上,没有写博客的习惯. 以后逐步分类整理出来,也算"复习"一遍了 - _ - . android的事 ...

  6. Android Handler消息传递机制

    在Android系统中,类Handler主要有如下两个作用. 在新启动的线程中发送消息. 在主线程中获取.处理消息. 类Handler在实现上述作用时,首先在新启动的线程中发送消息,然后在主线程中获取 ...

  7. Android学习笔记-事件处理之Handler消息传递机制

    内容摘要:Android Handler消息传递机制的学习总结.问题记录 Handler消息传递机制的目的: 1.实现线程间通信(如:Android平台只允许主线程(UI线程)修改Activity里的 ...

  8. Android事件传递机制详解及最新源码分析——ViewGroup篇

    版权声明:本文出自汪磊的博客,转载请务必注明出处. 在上一篇<Android事件传递机制详解及最新源码分析--View篇>中,详细讲解了View事件的传递机制,没掌握或者掌握不扎实的小伙伴 ...

  9. Android Touch事件传递机制 二:单纯的(伪生命周期)

    转载于:http://blog.csdn.net/yuanzeyao/article/details/38025165 在前一篇文章中,我主要讲解了Android源码中的Touch事件的传递过程,现在 ...

随机推荐

  1. AngularJS快速入门指南11:事件

    AngularJS拥有自己的HTML事件指令. ng-click指令 ng-click指令定义了AngularJS的click事件. <div ng-app="" ng-co ...

  2. CAS 实现单点登录 .NET MVC

    单点登录 Single Sign On,简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统. 单点登录原理 ...

  3. RAR和ZIP:压缩大战真相

    转:http://fqd2eh4y.blog.163.com/blog/static/69195855200801035015857 前言--王者归来? 等待足足两年之久,压缩霸主WinZip终于在万 ...

  4. Python面试题(一)

    **晚上在公司的论坛上看到一道面试题,题目如下:随机给定一字符串和字符,要求重排,比如:'abde','c'.重排之后变成'abcde' **看到他们给的答案很多都是二分法重排,既然是字符类的处理,当 ...

  5. How Tomcat works — 八、tomcat中的session管理

    在使用shiro的session的时候感觉对于tomcat中session的管理还不是特别清楚,而且session管理作为tomcat中比较重要的一部分还是很有必要学习的. 目录 概述 session ...

  6. Struts2入门3 深入学习

    Struts2入门3 深入学习 处理结果和异常 前言: Struts学习的差不多了,还有最后的一点就收官了就是结果处理和异常处理.前面学习Struts主要围绕就是Action以及struts.xml配 ...

  7. Solr调研总结

    http://wiki.apache.org/solr/ Solr调研总结 开发类型 全文检索相关开发 Solr版本 4.2 文件内容 本文介绍solr的功能使用及相关注意事项;主要包括以下内容:环境 ...

  8. 闲暇时间开发的个人app

    最近一段时间公司不是很忙,晚上基本没怎么加班.所以自己利用晚上在家的时间开发了一个app(奇趣营),其实自从转android开发以来,就有想过要自己开发一个app.一方面可以提升自己的经验:另一方面可 ...

  9. MAC电脑操作快捷键

    注:command即苹果键,也有人称为花键.ctrl即control键.escape即键盘左上角的esc键.space空格键. 屏幕捕捉快捷键 动作:保存到-快捷键 全屏捕捉-桌面(.pdf文件):c ...

  10. 简单谈谈Resource,Drawable和Bitmap之间的转换

    一直接触这些东西,还是归个类整理一下比较好. Resource -> Drawable Drawable draw1 = this.getResources().getDrawable(R.dr ...