Android触摸事件处理机制之requestDisallowInterceptTouchEvent

本文主要是介绍Android触摸事件处理机制之requestDisallowInterceptTouchEvent,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、触摸事件传递的规则

当手指触摸到屏幕时,系统就会调用相应的ViewonTouchEvent,并传入一系列的action。当有多个层级的View时,在父层级允许的情况下,这个action会一直向下传递直到遇到最深层的View。所以touch事件最先调用的是最底层ViewonTouchEvent,如果ViewonTouchEvent接收到某个touchaction并做了相应处理,最后有两种返回方式: retrun true returnfalsereturn true会告诉系统当前的View需要处理这次touch事件,以后系统发出的ACTION_MOVE,ACTION_UP等还是需要继续监听并接收的,而且这次的action已经被处理掉了,父层的View是不可能触发onTouchEvent了,所以每一个action最多只能有一个onTouchEvent接口返回true。如果返回false,便会通知系统,当前View不关心这一次的touch事件,此时这个action会传向父级,调用父级ViewonTouchEvent,但是这一次的touch事件之后发出的任何action,该View都不会再接受,onTouchEvent在这一次的touch事件中再也不会触发,也就是说一旦View返回false,那么之后的ACTION_MOVE,ACTION_UPaction就不会再传入这个view,但是下一次touch事件的action还是会传进来的。

   前面说到了底层的View能够接受到这次事件有一个前提:在父层级允许的情况下。假设不改变父层级的dispatch方法,在系统调用底层onTouchEvent之前会先调用父View的方法判断,父层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收到touchaction后调用这个方法那么父层View就不会再调用onInterceptTouchEvent了,也无法截获以后的action。

 

 

 

 

二、事例分析

     用例子总结一下onInterceptTouchEvent  onTouchEvent的调用顺序。   假设最高层ViewOuterLayout     中间层ViewInnerLayout     最底层ViewMyView

    调用的顺序是这样的(假设各个函数返回的都是false)OuterLayout.onInterceptTouchEvent  -> InnerLayout.onInterceptTouchEvent-> MyView.onTouchEvent -> InnerLayout.onTouchEvent ->OuterLayout.onTouchEvent

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

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

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

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

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

    如果两个控件一样大:

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

  • 只有TextView的单击事件有效

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

  • 触发LinearLayout的单击事件

 

 

 

public boolean onInterceptTouchEvent (MotionEvent ev)

 

Implement this methodto intercept all touch screen motion events. This allows you to watch events asthey are dispatched to your children, and take ownership of the current gestureat any point.

Using this functiontakes some care, as it has a fairly complicated interaction withView.onTouchEvent(MotionEvent),and using it requires implementing that method as well as this one in thecorrect way. Events will be received in the following order:

  1. You will receive the down event here.
  2. The down event will be handled either by a child of this view group, or given to your own onTouchEvent() method to handle; this means you should implement onTouchEvent() to return true, so you will continue to see the rest of the gesture (instead of looking for a parent view to handle it). Also, by returning true from onTouchEvent(), you will not receive any following events in onInterceptTouchEvent() and all touch processing must happen in onTouchEvent() like normal.
  3. For as long as you return false from this function, each following event (up to and including the final up) will be delivered first here and then to the target's onTouchEvent().
  4. If you return true from here, you will not receive any following events: the target view will receive the same event but with the actionACTION_CANCEL, and all further events will be delivered to your onTouchEvent() method and no longer appear here.

Parameters

ev

The motion event being dispatched down the hierarchy.

Returns

  • Return true to steal motion events from the children and have them dispatched to this ViewGroup through onTouchEvent(). The current target will receive an ACTION_CANCEL event, and no further messages will be delivered here.

这篇关于Android触摸事件处理机制之requestDisallowInterceptTouchEvent的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1145448

相关文章

PostgreSQL中MVCC 机制的实现

《PostgreSQL中MVCC机制的实现》本文主要介绍了PostgreSQL中MVCC机制的实现,通过多版本数据存储、快照隔离和事务ID管理实现高并发读写,具有一定的参考价值,感兴趣的可以了解一下... 目录一 MVCC 基本原理python1.1 MVCC 核心概念1.2 与传统锁机制对比二 Postg

Maven 配置中的 <mirror>绕过 HTTP 阻断机制的方法

《Maven配置中的<mirror>绕过HTTP阻断机制的方法》:本文主要介绍Maven配置中的<mirror>绕过HTTP阻断机制的方法,本文给大家分享问题原因及解决方案,感兴趣的朋友一... 目录一、问题场景:升级 Maven 后构建失败二、解决方案:通过 <mirror> 配置覆盖默认行为1. 配置示

Redis过期删除机制与内存淘汰策略的解析指南

《Redis过期删除机制与内存淘汰策略的解析指南》在使用Redis构建缓存系统时,很多开发者只设置了EXPIRE但却忽略了背后Redis的过期删除机制与内存淘汰策略,下面小编就来和大家详细介绍一下... 目录1、简述2、Redis http://www.chinasem.cn的过期删除策略(Key Expir

Go语言中Recover机制的使用

《Go语言中Recover机制的使用》Go语言的recover机制通过defer函数捕获panic,实现异常恢复与程序稳定性,具有一定的参考价值,感兴趣的可以了解一下... 目录引言Recover 的基本概念基本代码示例简单的 Recover 示例嵌套函数中的 Recover项目场景中的应用Web 服务器中

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

Jvm sandbox mock机制的实践过程

《Jvmsandboxmock机制的实践过程》:本文主要介绍Jvmsandboxmock机制的实践过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、背景二、定义一个损坏的钟1、 Springboot工程中创建一个Clock类2、 添加一个Controller

Dubbo之SPI机制的实现原理和优势分析

《Dubbo之SPI机制的实现原理和优势分析》:本文主要介绍Dubbo之SPI机制的实现原理和优势,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Dubbo中SPI机制的实现原理和优势JDK 中的 SPI 机制解析Dubbo 中的 SPI 机制解析总结Dubbo中

Java 的 Condition 接口与等待通知机制详解

《Java的Condition接口与等待通知机制详解》在Java并发编程里,实现线程间的协作与同步是极为关键的任务,本文将深入探究Condition接口及其背后的等待通知机制,感兴趣的朋友一起看... 目录一、引言二、Condition 接口概述2.1 基本概念2.2 与 Object 类等待通知方法的区别

Android NDK版本迭代与FFmpeg交叉编译完全指南

《AndroidNDK版本迭代与FFmpeg交叉编译完全指南》在Android开发中,使用NDK进行原生代码开发是一项常见需求,特别是当我们需要集成FFmpeg这样的多媒体处理库时,本文将深入分析A... 目录一、android NDK版本迭代分界线二、FFmpeg交叉编译关键注意事项三、完整编译脚本示例四

Android与iOS设备MAC地址生成原理及Java实现详解

《Android与iOS设备MAC地址生成原理及Java实现详解》在无线网络通信中,MAC(MediaAccessControl)地址是设备的唯一网络标识符,本文主要介绍了Android与iOS设备M... 目录引言1. MAC地址基础1.1 MAC地址的组成1.2 MAC地址的分类2. android与I