android中的事件类型分为按键事件和屏幕触摸事件,Touch事件是屏幕触摸事件的基础事件,有必要对它进行深入的了解。 
一个最简单的屏幕触摸动作触发了一系列Touch事件:

ACTION_DOWN->ACTION_MOVE->ACTION_MOVE->ACTION_MOVE...->ACTION_MOVE->ACTION_UP
当屏幕中包含一个ViewGroup,而这个ViewGroup又包含一个子view,这个时候android系统如何处理Touch事件呢?到底是ViewGroup来处理Touch事件,还是子view来处理Touch事件呢?我只能很肯定的对你说不一定。呵呵,为什么呢?看看下面我的调查结果你就明白了。

android系统中的每个View的子类都具有下面三个和TouchEvent处理密切相关的方法:
1)public boolean dispatchTouchEvent(MotionEvent ev) 这个方法用来分发TouchEvent
2)public boolean onInterceptTouchEvent(MotionEvent ev) 这个方法用来拦截TouchEvent
3)public boolean onTouchEvent(MotionEvent ev) 这个方法用来处理TouchEvent

当TouchEvent发生时:

首先Activity将TouchEvent传递给最顶层的View,TouchEvent最先到达最顶层 view 的 dispatchTouchEvent ,然后由 dispatchTouchEvent 方法进行分发,如果dispatchTouchEvent返回true ,则交给这个view的onTouchEvent处理,如果dispatchTouchEvent返回 false ,则交给这个 view 的 interceptTouchEvent 方法来决定是否要拦截这个事件,如果 interceptTouchEvent 返回 true ,也就是拦截掉了,则交给它的 onTouchEvent 来处理,如果 interceptTouchEvent 返回 false ,那么就传递给子 view ,由子 view 的 dispatchTouchEvent 再来开始这个事件的分发。如果事件传递到某一层的子 view 的 onTouchEvent 上了,这个方法返回了 false ,那么这个事件会从这个 view 往上传递,都是 onTouchEvent 来接收。而如果传递到最上面的 onTouchEvent 也返回 false 的话,这个事件就会“消失”,而且接收不到下一次事件。
通过语言描述这个处理逻辑很抽象,下面我就用代码来具体说明一下。
layout配置文件 activity_my.xml

<?xml version="1.0" encoding="utf-8"?>
<com.example.android_test01.MyLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    android:orientation="vertical" >

<com.example.android_test01.MyTextView
        android:id="@+id/tv"
        android:layout_width="200px"
        android:layout_height="200px"
        android:background="#FFFFFF"
        android:text="lzqdiy"
        android:textColor="#0000FF"
        android:textSize="40sp"
        android:textStyle="bold" />

</com.example.android_test01.MyLinearLayout>

节点层次很简单,一个LinearLayout中添加了一个TextView。

下面是java代码:

MyActivity

package com.example.android_test01;

import android.app.Activity;
import android.os.Bundle;

public class MyActivity extends Activity {
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_my);
 }
}

MyLinearLayout

package com.example.android_test01;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.LinearLayout;

public class MyLinearLayout extends LinearLayout {
 private final String TAG = "MyLinearLayout";

public MyLinearLayout(Context context, AttributeSet attrs) {
  super(context, attrs);
  Log.d(TAG, TAG);
 }

@Override
 public boolean dispatchTouchEvent(MotionEvent ev) {
  int action = ev.getAction();
  switch (action) {
  case MotionEvent.ACTION_DOWN:
   Log.d(TAG, "dispatchTouchEvent action:ACTION_DOWN");
   break;
  case MotionEvent.ACTION_MOVE:
   Log.d(TAG, "dispatchTouchEvent action:ACTION_MOVE");
   break;
  case MotionEvent.ACTION_UP:
   Log.d(TAG, "dispatchTouchEvent action:ACTION_UP");
   break;
  case MotionEvent.ACTION_CANCEL:
   Log.d(TAG, "dispatchTouchEvent action:ACTION_CANCEL");
   break;
  }
  return super.dispatchTouchEvent(ev);
 }

@Override
 public boolean onInterceptTouchEvent(MotionEvent ev) {
  int action = ev.getAction();
  switch (action) {
  case MotionEvent.ACTION_DOWN:
   Log.d(TAG, "onInterceptTouchEvent action:ACTION_DOWN");
   break;
  case MotionEvent.ACTION_MOVE:
   Log.d(TAG, "onInterceptTouchEvent action:ACTION_MOVE");
   break;
  case MotionEvent.ACTION_UP:
   Log.d(TAG, "onInterceptTouchEvent action:ACTION_UP");
   break;
  case MotionEvent.ACTION_CANCEL:
   Log.d(TAG, "onInterceptTouchEvent action:ACTION_CANCEL");
   break;
  }
  return false;
 }

@Override
 public boolean onTouchEvent(MotionEvent ev) {
  int action = ev.getAction();
  switch (action) {
  case MotionEvent.ACTION_DOWN:
   Log.d(TAG, "---onTouchEvent action:ACTION_DOWN");
   break;
  case MotionEvent.ACTION_MOVE:
   Log.d(TAG, "---onTouchEvent action:ACTION_MOVE");
   break;
  case MotionEvent.ACTION_UP:
   Log.d(TAG, "---onTouchEvent action:ACTION_UP");
   break;
  case MotionEvent.ACTION_CANCEL:
   Log.d(TAG, "---onTouchEvent action:ACTION_CANCEL");
   break;
  }
  return true;
 }
}

MyTextView

package com.example.android_test01;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.TextView;

public class MyTextView extends TextView {
 private final String TAG = "MyTextView";
 public MyTextView(Context context, AttributeSet attrs) {
  super(context, attrs);
 }

@Override
 public boolean dispatchTouchEvent(MotionEvent ev) {
  int action = ev.getAction();
  switch (action) {
  case MotionEvent.ACTION_DOWN:
   Log.d(TAG, "dispatchTouchEvent action:ACTION_DOWN");
   break;
  case MotionEvent.ACTION_MOVE:
   Log.d(TAG, "dispatchTouchEvent action:ACTION_MOVE");
   break;
  case MotionEvent.ACTION_UP:
   Log.d(TAG, "dispatchTouchEvent action:ACTION_UP");
   break;
  case MotionEvent.ACTION_CANCEL:
   Log.d(TAG, "onTouchEvent action:ACTION_CANCEL");
   break;
  }
  return super.dispatchTouchEvent(ev);
 }

@Override
 public boolean onTouchEvent(MotionEvent ev) {
  int action = ev.getAction();
  switch (action) {
  case MotionEvent.ACTION_DOWN:
   Log.d(TAG, "---onTouchEvent action:ACTION_DOWN");
   break;
  case MotionEvent.ACTION_MOVE:
   Log.d(TAG, "---onTouchEvent action:ACTION_MOVE");
   break;
  case MotionEvent.ACTION_UP:
   Log.d(TAG, "---onTouchEvent action:ACTION_UP");
   break;
  case MotionEvent.ACTION_CANCEL:
   Log.d(TAG, "---onTouchEvent action:ACTION_CANCEL");
   break;
  }
  return true;
 }
}

为了指代方便,下面将MyLinearLayout简称为L,将MyTextView简称为T,L.onInterceptTouchEvent=true 表示的含义为MyLinearLayout中的onInterceptTouchEvent方法返回值为true,通过程序运行时输出的Log来说明调用时序。

第1种情况 L.onInterceptTouchEvent=false&& L.onTouchEvent=true &&T.onTouchEvent=true 输出下面的Log:

D/MyLinearLayout(11865): dispatchTouchEvent action:ACTION_DOWN
D/MyLinearLayout(11865): onInterceptTouchEvent action:ACTION_DOWN
D/MyTextView(11865): dispatchTouchEvent action:ACTION_DOWN
D/MyTextView(11865): ---onTouchEvent action:ACTION_DOWN
D/MyLinearLayout(11865): dispatchTouchEvent action:ACTION_MOVE
D/MyLinearLayout(11865): onInterceptTouchEvent action:ACTION_MOVE
D/MyTextView(11865): dispatchTouchEvent action:ACTION_MOVE
D/MyTextView(11865): ---onTouchEvent action:ACTION_MOVE
...........省略其他的ACTION_MOVE事件Log
D/MyLinearLayout(11865): dispatchTouchEvent action:ACTION_UP
D/MyLinearLayout(11865): onInterceptTouchEvent action:ACTION_UP
D/MyTextView(11865): dispatchTouchEvent action:ACTION_UP
D/MyTextView(11865): ---onTouchEvent action:ACTION_UP
结论:TouchEvent完全由TextView处理。

第2种情况 L.onInterceptTouchEvent=false&& L.onTouchEvent=true &&T.onTouchEvent=false 输出下面的Log:

D/MyLinearLayout(13101): dispatchTouchEvent action:ACTION_DOWN
D/MyLinearLayout(13101): onInterceptTouchEvent action:ACTION_DOWN
D/MyTextView(13101): dispatchTouchEvent action:ACTION_DOWN
D/MyTextView(13101): ---onTouchEvent action:ACTION_DOWN
D/MyLinearLayout(13101): ---onTouchEvent action:ACTION_DOWN
D/MyLinearLayout(13101): dispatchTouchEvent action:ACTION_MOVE
D/MyLinearLayout(13101): ---onTouchEvent action:ACTION_MOVE
...........省略其他的ACTION_MOVE事件Log
D/MyLinearLayout(13101): dispatchTouchEvent action:ACTION_UP
D/MyLinearLayout(13101): ---onTouchEvent action:ACTION_UP
结论:TextView只处理了ACTION_DOWN事件,LinearLayout处理了所有的TouchEvent。

第3种情况 L.onInterceptTouchEvent=true&& L.onTouchEvent=true 输出下面的Log:

D/MyLinearLayout(13334): dispatchTouchEvent action:ACTION_DOWN
D/MyLinearLayout(13334): onInterceptTouchEvent action:ACTION_DOWN
D/MyLinearLayout(13334): ---onTouchEvent action:ACTION_DOWN
D/MyLinearLayout(13334): dispatchTouchEvent action:ACTION_MOVE
D/MyLinearLayout(13334): ---onTouchEvent action:ACTION_MOVE
...........省略其他的ACTION_MOVE事件Log
D/MyLinearLayout(13334): dispatchTouchEvent action:ACTION_UP
D/MyLinearLayout(13334): ---onTouchEvent action:ACTION_UP
结论:LinearLayout处理了所有的TouchEvent。

第4种情况 L.onInterceptTouchEvent=true&& L.onTouchEvent=false 输出下面的Log:

D/MyLinearLayout(13452): dispatchTouchEvent action:ACTION_DOWN
D/MyLinearLayout(13452): onInterceptTouchEvent action:ACTION_DOWN
D/MyLinearLayout(13452): ---onTouchEvent action:ACTION_DOWN
结论:LinearLayout只处理了ACTION_DOWN事件,那么其他的TouchEvent被谁处理了呢?答案是LinearLayout最外层的Activity处理了TouchEven

参考自:http://xiaxveliang.blog.163.com/blog/static/29708034201352064849512/

android的dispatchTouchEvent onInterceptTouchEvent onTouchEvent相关推荐

  1. Android中dispatchTouchEvent, onInterceptTouchEvent, onTouchEvent的理解

    [转]http://blog.csdn.net/guitk/article/details/7057155 onInterceptTouchEvent用于改变事件的传递方向.决定传递方向的是返回值,返 ...

  2. dispatchTouchEvent onInterceptTouchEvent onTouchEvent

    http://www.cnblogs.com/jqyp/archive/2012/04/25/2469758.html dispatchTouchEvent       分发 onInterceptT ...

  3. dispatchTouchEvent onInterceptTouchEvent onTouchEvent区分

      1. dispatchTouchEvent 是处理触摸事件分发,执行super.dispatchTouchEvent(ev),事件向下分发.   2. onInterceptTouchEvent是 ...

  4. Android中onInterceptTouchEvent、dispatchTouchEvent及onTouchEvent的调用顺序及内部原理

    在Android中需要经常对用户手势进行判断,在判断手势时需要精细的分清楚每个触摸事件以及每个View对事件的接收情况,在View,ViewGroup,Activity中都可以接收事件,在对事件进行处 ...

  5. Android事件分发之ViewGroup篇 -- ViewGroup的dispatchTouchEvent、onTouchEvent、onInterceptTouchEvent之间关系

    Android事件分发之ViewGroup篇(FatherViewGroup) – ViewGroup的dispatchTouchEvent.onTouchEvent.onInterceptTouch ...

  6. onInterceptTouchEvent / onTouchEvent响应事件的详析

    onInterceptTouchEvent(),onTouchEvent() 默认返回false 注:事件分发机制是由 dispatchTouchEvent() 开始分发的 onInterceptTo ...

  7. 从源码说说dispatchTouchEvent与onTouchEvent的关系以及OnTouchListener的用法

    为什么要说这个问题呢,这段时间还是在SeekBar上遇到一些问题,好像ADT并没有给seekBar在xml中提供enabled属性,虽然我们可以在代码中设置,但是它并不能实现下面这个需求,所以我们需要 ...

  8. (转)Android ViewGroup的onInterceptTouchEvent()事件分析

    onInterceptTouchEvent()的机制: 1. down事件首先会传递到onInterceptTouchEvent()方法 2. 如果该ViewGroup的onInterceptTouc ...

  9. Android onTouch 方法 和onTouchEvent 方法

    onTouch 是将触摸屏运动事件传递到目标视图,或查看是否是目标.' onTouch方法是view设置触摸时间的方法,结合OnTouchListener 使用, 下面是常见的2中按压的方法, pub ...

最新文章

  1. 一次失败的机巡平台对接经历分享
  2. 修改PostgreSQL数据库默认用户postgres的密码
  3. spring async_Spring Async和Java的8 CompletableFuture
  4. React开发(254):react项目理解 ant design 注意参数传递格式
  5. MySQL-InnoDB-事务
  6. 数据中心规划设计参考-(文章以GB 50174为参考基准)
  7. yED Editor Getting Start
  8. super-csv文档的部分翻译及基本使用
  9. Unity TileMap 2D 工具基础教程
  10. VVC/JEM代码学习26:m_pcTrQuant-transformN*N
  11. db2 jdbc 连接池_【转】java jdbc连接db2
  12. 985大学计算机专业起薪,985名校毕业生有多值钱?看完这份大学毕业生薪酬榜你就知道了...
  13. 关于erp系统最小采购量
  14. 查询话费余额php接口,PHP代码示例_PHP账号余额查询接口 | 微米-中国领先的短信彩信接口平台服务商...
  15. 数据库必知词汇:即席查询(Ad Hoc)
  16. React : React手脚架的使用
  17. GitHub Desktop 上实现项目的回滚操作,详细介绍
  18. [056] 微信公众平台开发视频教程全面来袭
  19. BT种子怎么用 BT种子怎么下载 BT种子是什么意思
  20. C语言中一个程序写完后怎么运行啊?

热门文章

  1. windows下的OpenGL视频播放器开发环境
  2. 计算机大专生的平均工资水平,大学/大专应届毕业生工资待遇分析报告 - 职业圈...
  3. [A Top-Down Approach][第一章 计算机网络和因特网]
  4. 深度时空残差网络在城市人流量预测中的应用
  5. php php_dbase.dll,php – 如何在Windows中解决“调用未定义函数dbase_open()”错误
  6. 关于win11管理员提权方法的补充技巧
  7. idea创建maven项目失败,没有src目录
  8. 断电断网等原因致使重新进入linux时系统进不去,进不了图形界面,出现/dev/sda2 recovery,clean,,,
  9. 机器学习(一)——什么是机器学习
  10. 实现登录和用户信息组件的按需展示