上一篇文章主要讲述了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. Android 学习手札(一) 应用程序架构

    1.资源列表 Android支持的资源列表 目   录 资源类型 描述 res/anim  XML  该目录用于存放帧(frame).动画或补间(tweened)动画文件 res/drawable   ...

  2. c#抽象工厂模式

    抽象工厂模式向客户端提供一个接口,使得客户端在不必指定具体类型的情况下,创建多个产品族中的对象.本文采取的仍然是接着以前的那个快餐店的例子. 现在,快餐店经常良好,逐渐发展壮大,为了适合不同地方人的饮 ...

  3. 前端,移动开发者,UI须懂: 不同设备的之间的尺寸

    在开发前端,移动APP,以及设计UI的时候,我们经常会去搜索不同设备之间的尺寸,来开始自己的工作,以保证显示效果达到更好,这里收集了现在常用的设备. 设备更新速度快,有些没罗列的,大家可以谷歌或者百度 ...

  4. DEDECMS使用SQL命令批量替换语句

    1.更改文章中的内容 update dede_addonarticle set body=replace(body,'原来的字符','替换后的字符') 2,替换文章标题 update dede_arc ...

  5. 分页插件jquery.simplePagination.js使用

    利用ecshop后台,利用插件更改分页显示样式遇到的问题,由于是利用Ajax获取数据进行页面数据更新?所以出现了以下情况: 初始化页面前 : 分页更新后: 点击后出现了分页插件内容消失, 原因:分页一 ...

  6. Linux删除用户

    删除用户 # userdel abc 该删除操作将用户删除但保留用户的home文件夹和邮件文件夹.并且当用户abc正在登录的时候,删除操作将失败,如下: # userdel abc userdel: ...

  7. openerp import namespace

    # If True, the Python modules inside the openerp namespace are made available# without the 'openerp. ...

  8. DEDECMS-helper小助手扩展

    今天在做DEDE动态调用模板的时候卡住了,后终被强大的互联网解决,记录解决问题的过程,以备后用 可以在/data/helper.inc.php中进行默认小助手初始化的设置,系统默认载入小助手 例如创建 ...

  9. PYTHON之批量文件指定字符串替换

    在工作应用中,运维自动化的基础是标准化. 而标准化的工作,是难点,在公司相关部门的配合. 那么,在有标准化之后,相应的部署脚本,就比较好写了. 贡献一个在类似环境下可以运用的东东.. 当然,可以写得更 ...

  10. java学习之面向对象概念

    思考的两种方式: 举例: 把大象放到冰箱里 一.面向过程 :[打开冰箱->把大象放里面->关上冰箱门]面向过程注重的是过程,也就是(动作[函数]),然后按照动作依次去执行就好了. 代表语言 ...