android 事件处理机制之requestDisallowInterceptTouchEvent

转: http://blog.csdn.net/chaihuasong/article/details/17499799

当手指触摸到屏幕时,系统就会调用相应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还是会传进来的。(我本人认为此短话不需要参考,简单读一下就可以向下看了。我认为文章的原作者在此处表述不准确,下面内容是没有什么问题的。 2015-1-31)
    前面说了底层的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。

@Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        getParent().requestDisallowInterceptTouchEvent(true);
        return super.dispatchTouchEvent(ev);
    }

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

public boolean onTouch(View v, MotionEvent event) {
     switch (event.getAction()) {
     case MotionEvent.ACTION_MOVE:
         pager.requestDisallowInterceptTouchEvent(true);
         break;
     case MotionEvent.ACTION_UP:
     case MotionEvent.ACTION_CANCEL:
         pager.requestDisallowInterceptTouchEvent(false);
         break;
     }
}

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

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

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

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

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

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

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

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

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

  • 只有TextView的单击事件有效

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

触发的是LinearLayout的单击事件

时间: 2024-10-14 02:04:30

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

理解Android事件处理机制

Android的事件处理机制分为两大类:基于监听器和基于回调 1.基于监听器的事件处理 这种处理方式和Java的GUI组件监听器的几乎一样,是一种委托式的处理办法.即如果View组件(事件源)被单击或者长按(事件)后,系统将这个单击事件委托给特定对象(监听器)处理,特定对象可以是Listener对象也可以是组件指定的事件处理方法.这里涉及到三个成员:事件源,事件和监听器.其中监听器是核心,它包含了事件的处理的实现. 下面是一个简单的Button监听器,采用匿名内部类的实现形式.界面布局文件只是线

Android事件处理机制

包括监听和回调两种机制. 1. 基于监听的事件处理: 事件监听包含三类对象,事件源,事件,事件监听器.Android的事件处理机制是一种委派式(Delegation)事件处理方式:普通组件(事件源)将整个事件处理委托给指定的对象(事件监听器):当该事件源发生指定的事件时,就通知所委托的事件监听器,由事件监听器来处理这个事件. 委派式事件处理方式类似于人类社会的分工协作.例如某单位发生火灾,该单位通常不自己处理该事件,而是通知消防局(事件监听器)去处理:发生治安事件,该单位通知公安局(事件监听器)

【Android应用开发技术:应用组件】Android事件处理机制

作者:郭孝星 微博:郭孝星的新浪微博 邮箱:[email protected] 博客:http://blog.csdn.net/allenwells Github:https://github.com/AllenWells 事件处理:不管是桌面应用还是手机应用都需要去响应用户的动作,这种为用户动作提供响应的机制就是事件处理. Android提供了两套事件处理机制,如下所示: 基于监听的事件处理 基于回调的事件处理 一般来说,基于回调的事件处理可用于处理一些通用性的事件,但对于某些特定的事件只能使

Android事件处理机制,Toast控件

package com.lxt008; import com.lxt008.R; import android.app.Activity; import android.os.Bundle; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.widget.Button; import android.widget.Toast; /** *

Android 事件处理全面剖析

篇外话:先来说下今天的日期,今天是2015年02月18日也就是大年三十,大家都在欢欢喜喜的准备过大年,活动也各式各样,搓麻将.打扑克.放烟花.准备看春晚,而我却还在敲代码,我只想说身为程序员的我们,真的屌丝的不能再屌丝了.虽然很屌丝,但我在这里还是要给大家拜个年,祝大家羊年喜气洋洋.写出来的代码少 bug.产品少改需求!当然当大家看到这篇 blog 的时候已经过完了年,因为我写这篇 blog 是在家里,而我家里木有网络,所以还得等到到了工作之地才能放出来,好了,回归正题. Android 事件处

Android基础入门教程——3.2 基于回调的事件处理机制

Android基础入门教程--3.2 基于回调的事件处理机制 标签(空格分隔): Android基础入门教程 本节引言 在3.1中我们对Android中的一个事件处理机制--基于监听的事件处理机制进行了学习,简单的说就是 为我们的事件源(组件)添加一个监听器,然后当用户触发了事件后,交给监听器去处理,根据不同的事件 执行不同的操作;那么基于回调的事件处理机制又是什么样的原理呢?好吧,还有一个问题:你知道 什么是方法回调吗?知道吗?相信很多朋友都是了解,但又说不出来吧!好了,带着这些疑问我们 对a

Android的Touch事件处理机制

Android的Touch事件处理机制比较复杂,特别是在考虑了多点触摸以及事件拦截之后. Android的Touch事件处理分3个层面:Activity层,ViewGroup层,View层. 首先说一下Touch事件处理的几条基本规则. 1.如果在某个层级没有处理ACTION_DOWN事件,那么该层就再也收不到后续的Touch事件了直到下一次ACTION_DOWN事件. 说明:a.某个层级没有处理某个事件指的是它以及它的子View都没有处理该事件. b.这条规则不适用于Activity层(它是顶

Android基础入门教程——3.1 基于监听的事件处理机制

Android基础入门教程--3.1.1 基于监听的事件处理机制 标签(空格分隔): Android基础入门教程 本节引言: 第二章我们学习的是Android的UI控件,我们可以利用这些控件构成一个精美的界面,但是仅仅是界面而已:下一步就要开始学习逻辑与业务实现了,本章节讲解的是Android的事件处理机制!何为事件处理机制?举个 简单的例子,比如点击一个按钮,我们向服务器发送登陆请求!当然,Android中的事件处理机制不止这一种, 比如屏幕发生选择,我们点击了屏幕上某个区域-简单点说,事件处

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

Android平台的事件处理机制有两种,一种是基于回调机制的,一种是基于监听接口的,现介绍第一种:基于回调机制的事件处理.Android平台中,每个View都有自己的处理事件的回调方法,开发人员可以通过重写View中的这些回调方法来实现需要的响应事件.当某个事件没有被任何一个View处理时,便会调用Activity中相应的回调方法.Android提供了以下回调方法供用户使用:1. onKeyDown:   功能:该方法是接口KeyEvent.Callback中的抽象方法,所有的View全部实现了