上一篇文章主要讲述了Android的TouchEvent的分发过程,其中有两个重要的函数:onInterceptTouchEvent和onTouchEvent,这两个函数可被重装以完成特定的逻辑。onInterceptTouchEvent的定义为于ViewGroup中,默认返回值为false,表示不拦截TouchEvent。onTouchEvent的定义位于View中,当ViewGroup要调用onTouchEvent时,会利用super.onTouchEvent。ViewGroup调用onTouchEvent默认返回false,表示不消耗touch事件,View调用onTouchEvent默认返回true,表示消耗了touch事件。考虑到onInterceptTouchEvent与onTouchEven在写UI的时候经常会用到,下面以一个例子来讲解一下。

先创建一个类MyView,继承自View

  1. public class MyView extends Button {
  2. private static final String TAG = MyView.class.getName();
  3. public MyView(Context context){
  4. super(context);
  5. }
  6. public MyView(Context context, AttributeSet attrs) {
  7. super(context, attrs);
  8. }
  9. @Override
  10. public boolean onTouchEvent(MotionEvent event) {
  11. Log.d(TAG, "onTouchEvent.");
  12. LogUtil.logAction(event, TAG);
  13. return super.onTouchEvent(event);
  14. }
  15. }

创建类MyLayout,继承自ViewGroup

  1. public class MyLayout extends FrameLayout{
  2. private static final String TAG = MyLayout.class.getName();
  3. public MyLayout(Context context) {
  4. super(context);
  5. }
  6. public MyLayout(Context context, AttributeSet attributeSet) {
  7. super(context, attributeSet);
  8. }
  9. @Override
  10. public boolean onInterceptTouchEvent(MotionEvent ev) {
  11. Log.d(TAG, "onInterceptTouchEvent");
  12. return super.onInterceptTouchEvent(ev);
  13. }
  14. @Override
  15. public boolean onTouchEvent(MotionEvent event) {
  16. Log.d(TAG, "onTouchEvent.");
  17. LogUtil.logAction(event, TAG);
  18. return super.onTouchEvent(event);
  19. }
  20. }

LogUtil.logAction()函数是用来打印MotionEvent的动作类型,代码如下:

  1. public class LogUtil {
  2. public static void logAction(MotionEvent event, final String tag) {
  3. int action = event.getAction();
  4. switch(action) {
  5. case MotionEvent.ACTION_DOWN:
  6. Log.d(tag, "action down");
  7. break;
  8. case MotionEvent.ACTION_CANCEL:
  9. Log.d(tag, "action cancel");
  10. break;
  11. case MotionEvent.ACTION_UP:
  12. Log.d(tag, "action up");
  13. break;
  14. case MotionEvent.ACTION_MOVE:
  15. Log.d(tag, "action move");
  16. break;
  17. default:
  18. Log.d(tag, "unknow action");
  19. }
  20. }
  21. }

布局文件main.xml将MyView嵌套在MyLayout中,代码如下:

  1. <view android:layout_width="fill_parent"
  2. android:layout_height="fill_parent"
  3. class="com.example.AndroidTest.MyLayout" xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:id="@+id/view">
  5. <com.example.AndroidTest.MyView
  6. android:layout_width="fill_parent"
  7. android:layout_height="wrap_content"
  8. android:text="hello" />
  9. </view>

MainActivity的代码如下:

  1. public class MainActivity extends Activity {
  2. public static final String TAG = "TouchDemoActivity";
  3. @Override
  4. public void onCreate(Bundle savedInstanceState)
  5. {
  6. super.onCreate(savedInstanceState);
  7. setContentView(R.layout.main);
  8. }
  9. }

程序启动后,截图如下。

下面分情况讨论程序的运行结果。

1、MyLayout的onInterceptTouchEvent返回false,MyView的onTouchEvent返回true

情况1:当点击蓝色框内的任意位置,只有MyLayout会接收事件,输出的Log如下:


可以看出,touch事件最后会被MyLayout的onTouchEvent接收到。

情况2: 点击红色框内的黑色区域,由于onInterceptTouchEvent()返回false,故MyView也能接收到touchEvent事件,输出的Log如下:

可以看出,由于MyView的onTOuchEvent默认返回True,消耗了touch事件,MyLayout中的onTOuchEvent将不会被调用。

当我们的手指按下黑色区域,停留几秒再抬起,得到的Log如下图:

可以看出,第一个事件的类型为action down,最后一个为action up,中间的都是action move的类型,这正好符合上一篇文章介绍的Android的手势定义。

2、MyLayout的onInterceptTouchEvent返回false,MyView的onTouchEvent返回false

改写MyView中onTouchEvent的代码,令其返回false

  1. @Override
  2. public boolean onTouchEvent(MotionEvent event) {
  3. Log.d(TAG, "onTouchEvent.");
  4. LogUtil.logAction(event, TAG);
  5. return false;
  6. }

由于MyView没有消耗touch事件,MyLayout的onTouchEvent将会被调用,打印的log如下:

可以看出,touch的类型只为action down。

3、MyLayout的onInterceptTouchEvent返回true

改写MyLayout中的onInterceptTouchEvent代码,令其返回true

  1. @Override
  2. public boolean onInterceptTouchEvent(MotionEvent ev) {
  3. Log.d(TAG, "onInterceptTouchEvent");
  4. return true;
  5. }

由于MyLayout拦截了touch事件,MyView中的onTouchEvent将不会被调用,log如下:

以上对Android的onInterceptTouchEvent和onTouchEvent的描述若有不妥之处,欢迎指正。

本文参考的代码出自:两分钟彻底让你明白Android中onInterceptTouchEvent与onTouchEvent(图文)!,感谢作者的无私分享。

Android Touch系统简介(二):实例详解onInterceptTouchEvent与onTouchEvent的调用过程的更多相关文章

  1. Android Touch系统简介(二):实例详解onInterceptTouchEvent与onTouchEvent的调用过程

    上一篇文章主要讲述了Android的TouchEvent的分发过程,其中有两个重要的函数:onInterceptTouchEvent和onTouchEvent,这两个函数可被重装以完成特定的逻辑.on ...

  2. Android核心分析之十五Android输入系统之输入路径详解

       Android用户事件输入路径 1 输入路径的一般原理 按键,鼠标消息从收集到最终将发送到焦点窗口,要经历怎样的路径,是Android GWES设计方案中需要详细考虑的问题.按键,鼠标等用户消息 ...

  3. Android网络请求框架AsyncHttpClient实例详解(配合JSON解析调用接口)

    最近做项目要求使用到网络,想来想去选择了AsyncHttpClient框架开进行APP开发.在这里把我工作期间遇到的问题以及对AsyncHttpClient的使用经验做出相应总结,希望能对您的学习有所 ...

  4. Android内存解析(二)— 详解内存,内部存储和外部存储

    总述 觉得十分有必要搞清楚内存,内部存储和外部存储的区别,还有我们在开发中真正将数据存在了手机的哪儿. 先提一个问题:手机设置的应用管理中,每个App下都有清除数据和清除缓存,清除的分别是哪里的数据? ...

  5. Ubuntu 14.10 下查看系统硬件信息(实例详解)

    linux查看系统的硬件信息,并不像windows那么直观,这里我罗列了查看系统信息的实用命令,并做了分类,实例解说. cpu lscpu命令,查看的是cpu的统计信息. blue@blue-pc:~ ...

  6. Linux 查看系统硬件信息(实例详解)

    原文链接:http://www.cnblogs.com/ggjucheng/archive/2013/01/14/2859613.html linux查看系统的硬件信息,并不像windows那么直观, ...

  7. [转载]查看Linux系统硬件信息实例详解

    linux查看系统的硬件信息,并不像windows那么直观,这里我罗列了查看系统信息的实用命令,并做了分类,实例解说. cpu lscpu命令,查看的是cpu的统计信息. blue@blue-pc:~ ...

  8. Appium+python自动化(三十四)- 有图有真相,很美很精彩 - 屏幕截图和Android APP类型简介(超详解)

    简介 在实际自动化项目运行过程中,很多时候App可以会出现各种异常,为了更好的定位问题,除了捕捉日志我们还需要对运行时的设备状态来进行截屏.从而达到一种“有图有真相”的效果. 截图方法 方法1 sav ...

  9. Android加载大图片实例详解

    摘要:在Android下采用ARGB表示颜色,每个像素占四个字节.其加载图片申请空间时与图片的实际大小没有关系,与像素有关系.

随机推荐

  1. 使用Raphael 画图(一) 基本图形 (javascript)

    Raphael是什么? Raphael 是一个用于在网页中绘制矢量图形的 Javascript 库.它使用 SVG W3C 推荐标准和 VML 作为创建图形的基础,你可以通过 JavaScript 操 ...

  2. Java初试

    另外在Java语言的代码内部书写文件路径时,需要注意大小写,大小写需要保持一致,路径中的文件夹名称区分大小写.由于’\’是Java语言中的特殊字符,所以在代码内部书写文件路径时,例如代表“c:\tes ...

  3. C# ERP开发框架

    C/S系统开发框架-企业版 V4.0 (Enterprise Edition) 简介: http://www.csframework.com/cs-framework-4.0.htm 视频下载: 百度 ...

  4. VLAN间通信----实验

        方法1.增加物理线路     需求:PC0连接SW的F0/1,PC1连接SW的F0/2; SW创建VLAN10,VLAN20; PC0划到VLAN10; PC1划到VLAN20; 现要求借用路 ...

  5. [BZOJ 3626] [LNOI2014] LCA 【树链剖分 + 离线 + 差分询问】

    题目链接: BZOJ - 3626 题目分析 考虑这样的等价问题,如果我们把一个点 x 到 Root 的路径上每个点的权值赋为 1 ,其余点的权值为 0,那么从 LCA(x, y) 的 Depth 就 ...

  6. OpenSource.com 评出 2014 年十佳开源软件

    Docker 应用容器平台 “电源管理和虚拟化以相同的方式允许我们从服务器利用率中获取最大的利益.如何真正的解决虚拟化,这世界第一难题仍然是普遍存在的.Docker 自从 2013 年开源以来,刚好在 ...

  7. Django 1.6 的测试驱动开发

    http://www.oschina.net/translate/django-1-6-test-driven-development 测试驱动开发(TDD)是一个迭代的开发周期,强调编写实际代码之前 ...

  8. Android Task 相关

    在日常开发过程中,只要涉及到activity,那么对task相关的东西总会或多或少的接触到,不过对task相关的一些配置的作用一直理解的还不是很透彻,官方文档在细节上说的也不够清楚,要透彻理解还是得自 ...

  9. The difference between text mode and binary mode with file streams

    FIO14-C. Understand the difference between text mode and binary mode with file streams     Skip to e ...

  10. 斜率优化(CDQ分治,Splay平衡树):BZOJ 1492: [NOI2007]货币兑换Cash

    Description Input 第一行两个正整数N.S,分别表示小Y 能预知的天数以及初始时拥有的钱数. 接下来N 行,第K 行三个实数AK.BK.RateK,意义如题目中所述 Output 只有 ...