上一篇文章主要讲述了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. java编码转化方案-备用

    import java.io.UnsupportedEncodingException; /** * 转换字符串的编码 */ public class changeCharSet { /** 7位AS ...

  2. Sql Server 时间格式

    问题引出: Sql Server 里 dateTime 数据类型,会精确到毫秒.如果我们 在插入一条数据的时候,使用 GetDate() 记录 这个记录插入的时间,则会插入当前时间,精确到毫秒.在查询 ...

  3. 利用sfntly的sfnttool.jar提取中文字体

    雨忆博客中提到了sfntly(具体介绍可以看:https://code.google.com/p/sfntly/),利用其中sfnttool.jar就可以提取只包含指定字符的字体,如果想在页面中通过@ ...

  4. C、C++、Java异或运算交换变量变量值的区别

    今天看到一位大神的博客,深受感触.决定也发一篇博客,证明一下我还活着. 于是我翻看以前学习时做的一些笔记,整理了一下,得到了一个关于异或运算交换变量变量值的笔记. 首先来看下面三组表达式,看起来他们都 ...

  5. cf B Bear and Strings

    题意:给你一个字符串,然后找多少区间内含有“bear”,输出数目: #include <cstdio> #include <cstring> #include <algo ...

  6. 温习H3C S5500的VLAN配置

    这,才是我想要的... ACCESS还是TRUNK TYPE?

  7. PPI是什么?如何计算?

    PPI,英文全称:pixels per inch,即像素每英寸,也叫像素密度,它是描述在水平的和垂直的方向上,每英寸距离的图像包含的像素(pixel)数目.因此PPI数值越高,即代表显示屏能够以越高的 ...

  8. SQL Server 全文搜索 配置、查询初体验

    原文:SQL Server 全文搜索 配置.查询初体验 一.使用SQL Server全文搜索配置 要使用SQL Server的全文搜索服务,需要进行如下配置. 1.开启全文搜索服务: 2.开启数据库的 ...

  9. rsync命令来实现将服务器端的文件备份到客户端

    rsync命令来实现将服务器端的文件备份到客户端

  10. River Hopscotch(二分)

    Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5473   Accepted: 2379 Description Every ...