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

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

Java ArrayList扩容机制 (源码解读)

结论:初始长度为10,若所需长度小于1.5倍原长度,则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义         1:数组默认长度         2:这是一个共享的空数组实例,用于明确创建长度为0时的ArrayList ,比如通过 new ArrayList<>(0),ArrayList 内部的数组 elementData 会指向这个 EMPTY_EL

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

【编程底层思考】垃圾收集机制,GC算法,垃圾收集器类型概述

Java的垃圾收集(Garbage Collection,GC)机制是Java语言的一大特色,它负责自动管理内存的回收,释放不再使用的对象所占用的内存。以下是对Java垃圾收集机制的详细介绍: 一、垃圾收集机制概述: 对象存活判断:垃圾收集器定期检查堆内存中的对象,判断哪些对象是“垃圾”,即不再被任何引用链直接或间接引用的对象。内存回收:将判断为垃圾的对象占用的内存进行回收,以便重新使用。

【Tools】大模型中的自注意力机制

摇来摇去摇碎点点的金黄 伸手牵来一片梦的霞光 南方的小巷推开多情的门窗 年轻和我们歌唱 摇来摇去摇着温柔的阳光 轻轻托起一件梦的衣裳 古老的都市每天都改变模样                      🎵 方芳《摇太阳》 自注意力机制(Self-Attention)是一种在Transformer等大模型中经常使用的注意力机制。该机制通过对输入序列中的每个元素计算与其他元素之间的相似性,

如何通俗理解注意力机制?

1、注意力机制(Attention Mechanism)是机器学习和深度学习中一种模拟人类注意力的方法,用于提高模型在处理大量信息时的效率和效果。通俗地理解,它就像是在一堆信息中找到最重要的部分,把注意力集中在这些关键点上,从而更好地完成任务。以下是几个简单的比喻来帮助理解注意力机制: 2、寻找重点:想象一下,你在阅读一篇文章的时候,有些段落特别重要,你会特别注意这些段落,反复阅读,而对其他部分

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk