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

相关文章

Redis客户端连接机制的实现方案

《Redis客户端连接机制的实现方案》本文主要介绍了Redis客户端连接机制的实现方案,包括事件驱动模型、非阻塞I/O处理、连接池应用及配置优化,具有一定的参考价值,感兴趣的可以了解一下... 目录1. Redis连接模型概述2. 连接建立过程详解2.1 连php接初始化流程2.2 关键配置参数3. 最大连

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

Go语言并发之通知退出机制的实现

《Go语言并发之通知退出机制的实现》本文主要介绍了Go语言并发之通知退出机制的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、通知退出机制1.1 进程/main函数退出1.2 通过channel退出1.3 通过cont

Spring Boot 中的默认异常处理机制及执行流程

《SpringBoot中的默认异常处理机制及执行流程》SpringBoot内置BasicErrorController,自动处理异常并生成HTML/JSON响应,支持自定义错误路径、配置及扩展,如... 目录Spring Boot 异常处理机制详解默认错误页面功能自动异常转换机制错误属性配置选项默认错误处理

Java中的xxl-job调度器线程池工作机制

《Java中的xxl-job调度器线程池工作机制》xxl-job通过快慢线程池分离短时与长时任务,动态降级超时任务至慢池,结合异步触发和资源隔离机制,提升高频调度的性能与稳定性,支撑高并发场景下的可靠... 目录⚙️ 一、调度器线程池的核心设计 二、线程池的工作流程 三、线程池配置参数与优化 四、总结:线程

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

Android ClassLoader加载机制详解

《AndroidClassLoader加载机制详解》Android的ClassLoader负责加载.dex文件,基于双亲委派模型,支持热修复和插件化,需注意类冲突、内存泄漏和兼容性问题,本文给大家介... 目录一、ClassLoader概述1.1 类加载的基本概念1.2 android与Java Class

Spring事务传播机制最佳实践

《Spring事务传播机制最佳实践》Spring的事务传播机制为我们提供了优雅的解决方案,本文将带您深入理解这一机制,掌握不同场景下的最佳实践,感兴趣的朋友一起看看吧... 目录1. 什么是事务传播行为2. Spring支持的七种事务传播行为2.1 REQUIRED(默认)2.2 SUPPORTS2

MySQL中的锁机制详解之全局锁,表级锁,行级锁

《MySQL中的锁机制详解之全局锁,表级锁,行级锁》MySQL锁机制通过全局、表级、行级锁控制并发,保障数据一致性与隔离性,全局锁适用于全库备份,表级锁适合读多写少场景,行级锁(InnoDB)实现高并... 目录一、锁机制基础:从并发问题到锁分类1.1 并发访问的三大问题1.2 锁的核心作用1.3 锁粒度分