本文转载自:http://blog.csdn.net/morgan_xww/article/details/9372285

跟touch事件相关的3个方法:
public boolean dispatchTouchEvent(MotionEvent ev);
   //用来分派event
public boolean onInterceptTouchEvent(MotionEvent ev); //用来拦截event
public boolean onTouchEvent(MotionEvent ev);          //用来处理event
 
拥有这三个方法的类:

Activity类: Activity dispatchTouchEvent();

onTouchEvent();
View容器(ViewGroup的子类): FrameLayout、LinearLayout……

ListView、ScrollVIew……
dispatchTouchEvent();

onInterceptTouchEvent();

onTouchEvent();
View控件(非ViewGroup子类): Button、TextView、EditText…… dispatchTouchEvent();

onTouchEvent();



个方法的用法:
dispatchTouchEvent() 用来分派事件。

其中调用了onInterceptTouchEvent()和onTouchEvent(),一般不重写该方法
onInterceptTouchEvent() 用来拦截事件。

ViewGroup类中的源码实现就是{return false;}表示不拦截该事件,

事件将向下传递(传递给其子View);

若手动重写该方法,使其返回true则表示拦截,事件将终止向下传递,

事件由当前ViewGroup类来处理,就是调用该类的onTouchEvent()方法
onTouchEvent() 用来处理事件。

返回true则表示该View能处理该事件,事件将终止向上传递(传递给其父View);

返回false表示不能处理,则把事件传递给其父View的onTouchEvent()方法来处理
【注】:ViewGroup的某些子类(GridView、ScrollView...)重写了onInterceptTouchEvent()方法,当发生ACTION_MOVE事件时,返回true进行拦截。


为了演示,重写了4个类:
总统 --> MyActivity
省长 --> MyFrameLayout
市长 --> MyLinearLayout
农民 --> MyTextView



【举个通俗易懂的例子】:
总统对省长说:我要吃红烧鱼
省长对市长说:你做个红烧鱼
市长对县长说:你做个红烧鱼
县长对农民说:你做个红烧鱼
   ……(农民做呀做,没做出来)
农民说:我尽力了,但真心不会做呀,饶了我吧
县长说:你个笨蛋,下次不找你了,看我来做
   ……(县长做呀做,没做出来)
县长对市长说:我尽力了,非常抱歉,我不会做
市长说:你个废物,要你何用,只能我自己来做了
   ……(市长做呀做,做成功了)
市长对省长说:红烧鱼做好了
省长说:不错,下次有事还找你
省长对总统说:红烧鱼做好了
总统说:不错,下次有事还找你
---------------------------
总统对省长说:我要吃水煮鱼
省长对市长说:你做个水煮鱼
市长说:县长连红烧鱼都搞不定,这次就不找他了,我自己亲自来做
 ……(市长做呀做,又成功了)
市长对省长说:水煮鱼做好了
省长说:不错,下次有事还找你
省长对总统说:水煮鱼做好了
总统说:不错,下次有事还找你
---------------------------
  • 按常理,领导都会把任务向下分派,一旦下面的人把事情做不好,就不会再把后续的任务交给下面的人来做了,只能自己亲自做,如果自己也做不了,就只能告诉上级不能完成任务,上级又会重复他的过程。
  • 另外,领导都有权利拦截任务,对下级隐瞒该任务,而直接自己去做,如果做不成,也只能向上级报告不能完成任务。

【1】TextView的clickable属性默认是false,所以TextView的onTouchEvent()方法默认返回false,程序输出如下:



     事件传递示意图:





【2】把TextView的clickable属性手动改成true,或者直接重写onTouchEvent()方法,使其返回true,程序输出如下:


      事件传递示意图:




【3】手动重写LinearLayout的onInterceptTouchEvent()方法,使其返回true,拦截事件,再重写onTouchEvent()方法,返回true,程序输出:


      事件传递示意图:




(1)这一系列的传递流程都是dispatchTouchEvent()方法来控制的,如果不人为地干预,事件将由上自下依次传递(因为默认是返回false不会拦截的),传递到最底层的View,就由它的onTouchEvent()方法来处理事件,若处理成功返回true,若处理失败返回false,事件依次向上传递,每个View都调用自己的onTouchEvent()方法来处理事件,若处理成功就终止传递,若处理失败就继续向上传递。
(2)经过人为的干预,若在向下传递的过程中被拦截了,即onInterceptTouchEvent()方法返回true,则事件将停止向下传递,直接由当前的onTouchEvent()方法来处理,若处理成功则OK,若处理不成功,则事件会向上传递。
(3)另外,dispatchTouchEvent()方法中还有“记忆”的功能,如果第一次事件向下传递到某View,它把事件继续传递交给它的子View,它会记录该事件是否被它下面的View给处理成功了,(怎么能知道呢?如果该事件会再次被向上传递到我这里来由我的onTouchEvent()来处理,那就说明下面的View都没能成功处理该事件);当第二次事件向下传递到该View,该View的dispatchTouchEvent()方法机会判断,若上次的事件由下面的view成功处理了,那么这次的事件就继续交给下面的来处理,若上次的事件没有被下面的处理成功,那么这次的事件就不会向下传递了,该View直接调用自己的onTouchEvent()方法来处理该事件。
(4)“记忆”功能的信息只在一系列事件完成之前有效,如从ACTION_DOWN事件开始,直到后续事件ACTION_MOVE,ACTION_UP结束后,“记忆”的信息就会清除。也就是说如果某View处理ACTION_DOWN事件失败了(onTouchEvent()返回false),那么后续的ACTION_MOVE,ACTION_UP等事件就不会再传递到该View了,由其父View自己来处理。在下一次发生ACTION_DOWN事件的时候,还是会传递到该View的。
  1. public class MyActivity extends Activity {
  2. @Override
  3. public void onCreate(Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. setContentView(R.layout.main);
  6. }
  7. @Override
  8. public boolean dispatchTouchEvent(MotionEvent ev) {
  9. Log.d("d", "【总统】任务<" + Util.actionToString(ev.getAction()) + "> : 需要分派");
  10. return super.dispatchTouchEvent(ev);
  11. }
  12. @Override
  13. public boolean onTouchEvent(MotionEvent ev) {
  14. boolean bo = false;
  15. Log.d("d", "【总统】任务<" + Util.actionToString(ev.getAction()) + "> : 下面都解决不了,下次再也不能靠你们了,哼…只能自己尝试一下啦。能解决?" + bo);
  16. return bo;
  17. }
  18. }
  1. public class MyFrameLayout extends FrameLayout
  2. {
  3. public MyFrameLayout(Context context, AttributeSet attrs){
  4. super(context, attrs);
  5. }
  6. @Override
  7. public boolean dispatchTouchEvent(MotionEvent ev) {
  8. Log.d("d", "【省长】任务<" + Util.actionToString(ev.getAction()) + "> : 需要分派");
  9. return super.dispatchTouchEvent(ev);
  10. }
  11. @Override
  12. public boolean onInterceptTouchEvent(MotionEvent ev) {
  13. boolean bo = false;
  14. Log.d("d", "【省长】任务<" + Util.actionToString(ev.getAction()) + "> : 拦截吗?" + bo);
  15. return bo;
  16. }
  17. @Override
  18. public boolean onTouchEvent(MotionEvent ev) {
  19. boolean bo = false;
  20. Log.d("d", "【省长】任务<" + Util.actionToString(ev.getAction()) + "> : 市长是个废物,下次再也不找你了,我自己来尝试一下。能解决?" + bo);
  21. return bo;
  22. }
  23. }
  1. public class MyLinearLayout extends LinearLayout{
  2. public MyLinearLayout(Context context, AttributeSet attrs) {
  3. super(context, attrs);
  4. }
  5. @Override
  6. public boolean dispatchTouchEvent(MotionEvent ev) {
  7. Log.d("d", "【市长】任务<" + Util.actionToString(ev.getAction()) + "> : 需要分派");
  8. return super.dispatchTouchEvent(ev);
  9. }
  10. @Override
  11. public boolean onInterceptTouchEvent(MotionEvent ev) {
  12. boolean bo = false;
  13. Log.d("d", "【市长】任务<" + Util.actionToString(ev.getAction()) + "> : 拦截吗?" + bo);
  14. return bo;
  15. }
  16. @Override
  17. public boolean onTouchEvent(MotionEvent ev) {
  18. boolean bo = false;
  19. Log.d("d", "【市长】任务<" + Util.actionToString(ev.getAction()) + "> : 农民真没用,下次再也不找你了,我自己来尝试一下。能解决?" + bo);
  20. return bo;
  21. }
  22. }
  1. public class MyTextView extends TextView
  2. {
  3. public MyTextView(Context context, AttributeSet attrs){
  4. super(context, attrs);
  5. }
  6. @Override
  7. public boolean dispatchTouchEvent(MotionEvent ev){
  8. Log.d("d", "【农民】任务<" + Util.actionToString(ev.getAction()) + "> : 需要分派,我下面没人了,怎么办?自己干吧");
  9. return super.dispatchTouchEvent(ev);
  10. }
  11. @Override
  12. public boolean onTouchEvent(MotionEvent ev){
  13. boolean bo = true;
  14. Log.d("d", "【农民】任务<" + Util.actionToString(ev.getAction()) + "> : 自己动手,埋头苦干。能解决?" + bo);
  15. return bo;
  16. }
  17. }

Android TouchEvent事件传递机制的更多相关文章

  1. 【转】Android TouchEvent事件传递机制

    Android TouchEvent事件传递机制   事件机制参考地址: http://www.cnblogs.com/sunzn/archive/2013/05/10/3064129.html ht ...

  2. Android touch 事件传递机制

    前言: (1)在自定义view的时候经常会遇到事件拦截处理,比如在侧滑菜单的时候,我们希望在侧滑菜单里面有listview控件,但是我们希望既能左右滑动又能上下滑动,这个时候就需要对触摸的touch事 ...

  3. Android 的事件传递机制,详解

    Android 的事件传递机制,详解 前两天和一个朋友聊天的时候.然后说到事件传递机制.然后让我说的时候,忽然发现说的不是非常清楚,事实上Android 的事件传递机制也是知道一些,可是感觉自己知道的 ...

  4. Android Touch事件传递机制 二:单纯的(伪生命周期)

    转载于:http://blog.csdn.net/yuanzeyao/article/details/38025165 在前一篇文章中,我主要讲解了Android源码中的Touch事件的传递过程,现在 ...

  5. Android Touch事件传递机制 一: OnTouch,OnItemClick(监听器),dispatchTouchEvent(伪生命周期)

      ViewGroup View  Activity dispatchTouchEvent 有 有 有 onInterceptTouchEvent 有 无 无 onTouchEvent 有 有 有 例 ...

  6. Android Touch事件传递机制通俗讲解

    在讲正题之前我们讲一段有关任务传递的小故事,抛砖迎玉下: 话说一家软件公司,来一个任务,分派给了开发经理去完成: 开发经理拿到,看了一下,感觉好简单,于是 开发经理:分派给了开发组长 开发组长:分派给 ...

  7. Android Touch事件传递机制 二:单纯的(伪生命周期) 这个清楚一点

    转载于:http://blog.csdn.net/yuanzeyao/article/details/38025165 在前一篇文章中,我主要讲解了Android源码中的Touch事件的传递过程,现在 ...

  8. Android Touch事件传递机制引发的血案

    尊重原创:http://blog.csdn.net/yuanzeyao/article/details/38942135 关于Android Touch事件传递机制我之前也写过两篇文章,自觉得对Tou ...

  9. Android触摸事件传递机制

    简单梳理一下Android触摸事件传递机制的知识点. 一.View与ViewGroup的关系 View和ViewGroup二者的继承关系如下图所示: View是Android中最基本的一种UI组件,它 ...

随机推荐

  1. JVM-内存分配与回收策略

    简单介绍一下Java技术体系下的Java虚拟机内存分配与回收策略.  1.对象优先在Eden分配  大多数情况下,对象在新生代Eden区中分分配.当Eden区已没有足够空间进行分配时,虚拟机将发起一次 ...

  2. 为什么SQL语句加 1=1

    是为了链接下面的查询条件条件,也或者是替换没有查询条件的语句.比如:要把检索条件作为一个参数传递给SQL,那么,当这个检索语句不存在的话就可以给它赋值为1=1.这样就避免了SQL出错,也就可以把加条件 ...

  3. R——启程——豆瓣影评分析

    专业统计的我,自然免不了学R的,今天仔细看了这篇教程(感谢学姐的推荐@喜欢算法的女青年),就学着用R仿照着做一个,作为R语言学习的起点吧. 影评数据是用python爬的,之后会在python爬虫系列补 ...

  4. iOS字体设置

    label.font = [UIFont fontWithName:@"Arial-BoldItalicMT" size:24]; 字体名如下: Font Family: Amer ...

  5. xp默认安装路径及本地用户配置文件存放路径修改

    xp默认安装路径及本地用户配置文件存放路径修改 修改注册表可能会造成您的系统崩溃或数据丢失,请先行备份操作系统,以备不测!!! 备份注册表步骤: 1.在“桌面”上按快捷键“Ctrl+R”,调出“运行” ...

  6. 重学STM32---(八)----SDIO

    1. SDIO(SD/SDIO MMC卡主机模块)在AHB外设总线和多媒体卡(MMC).SD存储卡.SDIO卡和CE-ATA设备间提供了操作接口.(SDIO没有SPI兼容的通信模式 ) 1.1.什么是 ...

  7. Magento控制器

    提到模型-视图-控制器这种MVC架构,要追溯到Smalltalk编程语言和Xerox Parc.从那个时候开始,就有许多系统将自己描述为MVC架构.这些系统虽然在某些地方有细微差别,但都实现了数据层, ...

  8. re-id 资料集

    Shengcai Liao: http://www.cbsr.ia.ac.cn/users/scliao/

  9. Word Ladder

    Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest t ...

  10. css中的width,height,属性与盒模型的关系

    这段话很容易记住盒模型: css中盒子模型包含属性margin.border.padding.content,他们可以把它转移到我们日常生活中的盒子(箱 子)上来理解,日常生活中所见的盒子也具有这些属 ...