当手指触摸到屏幕时,系统就会调用相应View的onTouchEvent,并传入一系列的action。当有多个层级的View时,在父层级允许的情 况下,这个action会一直向下传递直到遇到最深层的View。所以touch事件最先调用的是最底层View的onTouchEent,如果View 的onTouchEvent接收到某个touch action并作了相应处理,最后有两种返回方式return true和return false;return true会告诉系统当前的View需要处理这次的touch事件,以后的系统发出的ACTION_MOVE,ACTION_UP还是需要继续监听并接收 的,而且这次的action已经被处理掉了,父层的View是不可能出发onTouchEvent了。所以每一个action最多只能有一个 onTouchEvent接口返回true。如果return false,便会通知系统,当前View不关心这一次的touch事件,此时这个action会传向父级,调用父级View的onTouchEvent。 但是这一次的touch事件之后发出的任何action,该View都不会再接受,onTouchEvent在这一次的touch事件中再也不会触发,也 就是说一旦View返回false,那么之后的ACTION_MOVE,ACTION_UP等ACTION就不会在传入这个View,但是下一次 touch事件的action还是会传进来的。
   
前面说了底层的View能够接收到这次的事件有一个前提条件:在父层级允许的情况下。假设不改变父层级的dispatch方法,在系统调用底层
onTouchEvent之前会先调用父View的onInterceptTouchEvent方法判断,父层View是不是要截获本次touch事件之
后的action。如果onInterceptTouchEvent返回了true,那么本次touch事件之后的所有action都不会再向深层的
View传递,统统都会传给负层View的onTouchEvent,就是说父层已经截获了这次touch事件,之后的action也不必询问
onInterceptTouchEvent,在这次的touch事件之后发出的action时onInterceptTouchEvent不会再次调
用,知道下一次touch事件的来临。如果onInterceptTouchEvent返回false,那么本次action将发送给更深层的View,
并且之后的每一次action都会询问父层的onInterceptTouchEvent需不需要截获本次touch事件。只有ViewGroup才有
onInterceptTouchEvent方法,因为一个普通的View肯定是位于最深层的View,touch事件能够传到这里已经是最后一站了,肯
定会调用View的onTouchEvent。
对于底层的View来说,有一种方法可以阻止父层的View截获touch事件,就是调用
getParent().requestDisallowInterceptTouchEvent(true);方法。一旦底层View收到touch的
action后调用这个方法那么父层View就不会再调用onInterceptTouchEvent了,也无法截获以后的action。
用例子总结一下onInterceptTouchEvent和onTouchEvent的调用顺序:
假设最高层View叫OuterLayout,中间层View叫InnerLayout,最底层View叫MyVIew。调用顺序是这样的(假设各个函数返回的都是false)
OuterLayout.onInterceptTouchEvent->InnerLayout.onInterceptTouchEvent->MyView.onTouchEvent->InnerLayout.onTouchEvent->OuterLayout.onTouchEvent。

  1. @Override
  2. public boolean dispatchTouchEvent(MotionEvent ev) {
  3. getParent().requestDisallowInterceptTouchEvent(true);
  4. return super.dispatchTouchEvent(ev);
  5. }

这句话是告诉父view,我的事件自己处理

  1. public boolean onTouch(View v, MotionEvent event) {
  2. switch (event.getAction()) {
  3. case MotionEvent.ACTION_MOVE:
  4. pager.requestDisallowInterceptTouchEvent(true);
  5. break;
  6. case MotionEvent.ACTION_UP:
  7. case MotionEvent.ACTION_CANCEL:
  8. pager.requestDisallowInterceptTouchEvent(false);
  9. break;
  10. }
  11. }

也可以写成类似于上面那样,当用户按下的时候,我们告诉父组件,不要拦截我的事件(这个时候子组件是可以正常响应事件的),拿起之后就会告诉父组件可以阻止。

还有一个关于子控件和父控件的事件响应问题
当父控件中有子控件的时候,并且父控件和子空间都有事件处理(比如单击事件)。这时,点击子控件,父控件的单击事件就无效了。

比如一个LinearLayout里面有一个子控件TextView,但是TextView的大小没有LinearLayout大

①如果LinearLayout和TextView都设置了单击事件,那么

  • 点击TextView区域的时候,触发的是TextView的事件,
  • 点击TextView以外的区域的时候,还是触发的LinearLayout的事件。

②如果LinearLayout设置了单击事件,而TextView没有设置单击事件的话,那么

  • 不管单击的是TextView区域,还是TextView以外的区域,都是触发的LinearLayout的单击事件

如果LinearLayout的大小和TextView一样的话,那么

①如果LinearLayout和TextView都设置了单击事件,那么

  • 只有TextView的单击事件有效

②如果LinearLayout设置了单击事件,而TextView没有设置单击事件的话,那么

触发的是LinearLayout的单击事件

android 事件处理机制之requestDisallowInterceptTouchEvent的更多相关文章

  1. Android事件处理机制

    包括监听和回调两种机制. 1. 基于监听的事件处理: 事件监听包含三类对象,事件源,事件,事件监听器.Android的事件处理机制是一种委派式(Delegation)事件处理方式:普通组件(事件源)将 ...

  2. Android的两种事件处理机制

    UI编程通常都会伴随事件处理,Android也不例外,它提供了两种方式的事件处理:基于回调的事件处理和基于监听器的事件处理. 对于基于监听器的事件处理而言,主要就是为Android界面组件绑定特定的事 ...

  3. Android的Touch事件处理机制

    Android的Touch事件处理机制比较复杂,特别是在考虑了多点触摸以及事件拦截之后. Android的Touch事件处理分3个层面:Activity层,ViewGroup层,View层. 首先说一 ...

  4. Android的事件处理机制详解(二)-----基于监听的事件处理机制

    基于监听的事件处理机制 前言: 我们开发的app更多的时候是需要与用户的交互----即对用户的操作进行响应 这就涉及到了android的事件处理机制; android给我们提供了两套功能强大的处理机制 ...

  5. Android的事件处理机制(一)------基于回调机制的事件处理

    Android平台的事件处理机制有两种,一种是基于回调机制的,一种是基于监听接口的,现介绍第一种:基于回调机制的事件处理.Android平台中,每个View都有自己的处理事件的回调方法,开发人员可以通 ...

  6. Android平台的事件处理机制和手指滑动例子

    Android平台的事件处理机制有两种 基于回调机制的事件处理:Android平台中,每个View都有自己的处理事件的回调方法,开发人员可以通过重写View中的这些回调方法来实现需要的响应事件. 基于 ...

  7. Android——事件处理模型一(基于回调机制的事件处理)(转)

    Android平台的事件处理机制有两种,一种是基于回调机制的,一种是基于监听接口的,现介绍第一种:基于回调机制的事件处理.Android平台中,每个View都有自己的处理事件的回调方法,开发人员可以通 ...

  8. Android基础新手教程——3.1 基于监听的事件处理机制

    Android基础新手教程--3.1.1 基于监听的事件处理机制 标签(空格分隔): Android基础新手教程 本节引言: 第二章我们学习的是Android的UI控件,我们能够利用这些控件构成一个精 ...

  9. Android的事件处理机制之基于回调的事件处理

    回调机制 如果说事件监听机制是一种委托式的事件处理,那么回调机制则与之相反,对于基于回调的事件处理模型来说,事件源与事件监听器是统一的,换种方法说事件监听器完全消失了,当用户在GUI组件上激发某个事件 ...

随机推荐

  1. __cdecl __stdcall __fastcall之函数调用约定讲解

    首先讲解一下栈帧的概念: 从逻辑上讲,栈帧就是一个函数执行的环境:函数参数.函数的局部变量.函数执行完后返回到哪里等等. 实现上有硬件方式和软件方式(有些体系不支持硬件栈) 首先应该明白,栈是从高地址 ...

  2. JavaScript之arguments对象讲解

    javascript的arguments对象类似于PHP的extract()函数实现. 在不确定函数参数个数的情况下,可以通过arguments访问参数,并以索引0为起始. function sayH ...

  3. .NET设计模式(13):享元模式(Flyweight Pattern)(转)

    摘要:面向对象的思想很好地解决了抽象性的问题,一般也不会出现性能上的问题.但是在某些情况下,对象的数量可能会太多,从而导致了运行时的代价.那么我们如何去避免大量细粒度的对象,同时又不影响客户程序使用面 ...

  4. Hadoop的RPC框架介绍

    为什么会引入RPC: RPC采用客户机/服务器模式.请求程序就是一个客户机,而服务提供程序就是一个服务器.当我们讨论HDFS的,通信可能发生在: Client-NameNode之间,其中NameNod ...

  5. 从CMO到龙泉寺弟子:佛法改变人生

    今天,移动精英开发社为大家请来了佛家弟子孫濟初师兄给大家分享学佛心得.濟初师兄根据自己的亲身经历,讲述了佛法对他人生的影响,以及他所获得的启示.本文系国内ITOM管理平台OneAPM授权转载. 孫濟初 ...

  6. 游戏引擎网络开发者的64做与不做(二A):协议与API

    [编者按]在这个系列之前的文章"游戏引擎网络开发者的64做与不做(一):客户端方面"中,Sergey介绍了游戏引擎添加网络支持时在客户端方面的注意点.本文,Sergey则将结合实战 ...

  7. 【动态规划】 之最长公共子序列LCS

    int lcs_len(char *a, char *b, int c[][N]){ int aLen=strlen(a), bLen=strlen(b), i,j; ; i<=aLen; i+ ...

  8. UVA 11038 - How Many O's? 计算对答案的贡献

    题意: 求[n, m]之间包含0的数字的个数题解:转化为求solve(n) - solve(m-1)的前缀问题 对于求0到n的解,我们举例 n = 25789 对于8这位,让其为0对答案的贡献是 (0 ...

  9. Codeforces Round #335 (Div. 2) D. Lazy Student 贪心

    D. Lazy Student   Student Vladislav came to his programming exam completely unprepared as usual. He ...

  10. MyEclipse 2015 CI

    系统 win8.1 MyEclipse 2015 CI 激活后可用 激活工具 地址:http://download.csdn.net/detail/trep10000/8305577