上一篇文章主要讲述了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. 运用BeanUtils构建通用的查询 更新方法(个人拙作,不喜勿喷)

    ------------------------------------更新方法----------------------------------- public void update(Strin ...

  2. U盘美化(更换U盘logo和页面背景软件)

    U盘内新建txt文本后,输入 [autorun] ICON=ooopic_1459309050.ico 保存的文件名包括后缀更改为autorun.inf 必须为icon图标

  3. 在静态页面html中跳转传值

    在html中通过"?"传值--------<a href="index2.html?name=caoy">静态传值</a> 在跳转到的页 ...

  4. 【随记】VS异常:HRESULT: 0x80070057 (E_INVALIDARG)) 解决方案

    今天公司突然断电后,来电重启VS,调试WebService时报错: 未能加载文件或程序集 “XXX” 或它的某一个依赖项.系统找不到指定的文件.  说明: 执行当前 Web 请求期间,出现未处理的异常 ...

  5. Bootstrap_表单_按钮

    一.多标签支持 一般制作按钮除了使用<button>标签元素之外,还可以使用<input type="submit">和<a>标签等. 同样,在 ...

  6. Python入门,新手之路

    1.开始使用Python: 从上一篇中我们提到了第一个Python,print("Hello World!")程序说起,看到这一句话,你有没有想过如果括号中的语句不是Hello W ...

  7. Resilio-sync auto restart

    syncheck.sh #!/bin/sh if [ $(pgrep xxxrslsync) ]; then echo && date >> /home/pi/sync/s ...

  8. run_command函数分析

    一.概述 位置:common/main.c 功能:根据传入参数(命令),在命令存储区(.u_boot_cmd)中查找对应的命令,找到命令并调用对应的函数执行 流程: 二.分析 1.函数说明信息 /** ...

  9. bzoj1233: [Usaco2009Open]干草堆tower

    Description 奶牛们讨厌黑暗. 为了调整牛棚顶的电灯的亮度,Bessie必须建一座干草堆使得她能够爬上去够到灯泡 .一共有N大包的干草(1<=N<=100000)(从1到N编号) ...

  10. 老oj曼哈顿最小生成树

    Description 平面坐标系xOy内,给定n个顶点V = (x , y).对于顶点u.v,u与v之间的距离d定义为|xu – xv| + |yu – yv| 你的任务就是求出这n个顶点的最小生成 ...