Android View滑动冲突解决方案

文章目录

  • 前言
  • 1. 滑动冲突
  • 2. 解决方案
    • 2.1 外部解决法
    • 2.2 内部拦截法
  • 参考资料

前言

本文需要读者对View事件分发的流程有基本的了解,如果还未完全理解事件分发流程的,需要先学习相关部分内容,这部分可以参考我的上一个博客:

Android View点击事件分发原理,源码解读
https://blog.csdn.net/qq_41872247/article/details/139880308

前提:
现在来说我们如果是使用Google官方的View嵌套,比如ViewPager2,ScrollView,RecyclerView等滑动视图的话,哪怕你出现了两个滑动视图嵌套的情况,一般来说也不会出现滑动冲突的场景,因为Google官方经过多年的迭代之后,对于自带的这些视图常用场景的处理都已经很完善了。

已经实测过不会出现滑动冲突的场景(不分先后顺序):

  1. RecyclerView套RecyclerView
  2. ScrollView套RecyclerView
  3. ViewPager2套RecyclerView
  4. ViewPager2套ScrollView,ScrollView套ViewPager2

所以,想要讲述滑动冲突这个问题怎么解决,最需要的是先有一个冲突的场景案例。

1. 滑动冲突

一般而言,滑动冲突只有以下三种场景。

  1. 内部控件的滑动方向和外部控件的滑动方向不同(比如内部视图是左右滑动,而外部视图是上下滑动)
  2. 内部控件的滑动方向和外部控件的滑动方向相同(比如内部视图和外部视图都是上下滑动)
  3. 前两者结合的嵌套滑动问题。

2. 解决方案

我们在处理滑动冲突的时候,无非都是遵循一个原则:
当用户想要操作里面那个视图的滑动功能时,让里面的视图处理掉滑动点击事件。
当用户想要操作外面那个视图的滑动功能时,让外面的视图处理掉滑动点击事件。

基于这两种场景,我们在处理滑动冲突的时候就有了外部解决法和内部解决法。
对于滑动方向不同的场景,用外部解决法比较容易写代码
对于滑动方向相同的场景,用内部解决法比较容易写代码

2.1 外部解决法

在外部视图的onInterceptTouchEvent进行逻辑判断,如果是父布局需要滑动,就拦截该事件,否则就放过该事件,代码如下:

override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
    when (ev?.action) {
        MotionEvent.ACTION_DOWN -> {
            return false
        }
        MotionEvent.ACTION_MOVE -> {
            if (这是父布局的滑动事件) {
                return true
            } else {
                return false
            }
        }
        MotionEvent.ACTION_UP,
        MotionEvent.ACTION_CANCEL -> {
            return false
        }
    }
    return super.onInterceptTouchEvent(ev)
}

2.2 内部拦截法

想要让子布局达成这个条件,就需要两点:

  1. 让子布局处理滑动逻辑的视图,确实的消化掉滑动事件,也就是让内部View处理dispatchTouchEvent这个方法最终return true。
  2. 让父布局跳过处理滑动逻辑的视图,不拦截该事件,好让事件确实的能流到内部的视图中而不是被外部视图直接处理,也就是让父布局的拦截方法onInterceptTouchEvent这个方法return false。

对于内部拦截法而言,由于他不直接修改父布局的onInterceptTouchEvent方法,所以他需要另外一个API:parent.requestDisallowInterceptTouchEvent(),用这个API来变相控制父布局的onInterceptTouchEvent返回true或false

同时要注意,由于点击事件的延续性,无论这个滑动事件最终是父布局处理还是子布局处理,最开始的DOWN事件父布局不要拦截,子布局在DOWN事件固定return true。

他的大体代码结构如下:

override fun dispatchTouchEvent(event: MotionEvent?): Boolean {
    when(event?.action) {
        MotionEvent.ACTION_DOWN -> {
        	parent.requestDisallowInterceptTouchEvent(true)
        }
        MotionEvent.ACTION_MOVE -> {
        	if (这是子布局的滑动事件)
            	parent.requestDisallowInterceptTouchEvent(true)
            else
            	parent.requestDisallowInterceptTouchEvent(false)
        }
        MotionEvent.ACTION_CANCEL,
        MotionEvent.ACTION_UP -> {
            parent.requestDisallowInterceptTouchEvent(false)
        }
    }
   
   // 如果是子布局的滑动事件,一定要保证该方法return true,这证明了子视图确实的消费了该点击事件
   // 这样父布局才不会重复处理该事件,引起滑动冲突
   // 由于点击事件的延续性,DOWN固定return true
   if (这是子布局的滑动事件 || event?.action == MotionEvent.ACTION_DOWN)
       super.dispatchTouchEvent(event)
       return true
   else 
       return super.dispatchTouchEvent(event)
}

参考资料

https://blog.csdn.net/wekajava/article/details/120623229

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/775212.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot整合Dubbo的快速使用教程

目录 一、什么是Dubbo? 二、SpringBoot整合Dubbo 1、父工程引入依赖 2、各个Dubbo服务子模块引入依赖 3、服务提供者 (1)启动类添加注解EnableDubbo (2)服务类添加注解DubboService (3)配置文件…

Linux系统的基础知识和常用命令

1、什么是Linux? 是一种免费使用和自由传播的类UNIX操作系统,其内核由林纳斯本纳第克特托瓦兹于1991年10月5日首次发布,它主要受到Minix和Unix思想的启发,是一个基于POSIX的多用户、多任务、支持多线程和多CPU的操作系统。它能运行…

C++学习笔记二

一、常量 1.用const关键字声明常量变量 const常量变量在定义时必须进行初始化,并且不能通过赋值来改其值 const double gravity { 9.8 }; //首选在类型之前使用const int const sidesInSquare { 4 }; // “east const”风格,可以,但不是首…

Java实习手册(小白也看得懂)

秃狼说 距离俺发布的学习路线已经六个月了,那我给小伙伴的学习周期是四五个月左右,我相信大多的小伙伴已经学习的差不多了。正好赶上暑期实习的阶段,在暑期找到实习就成为暑期的头等大事。 实习经验在校招的起到决定性的作用,所…

单元测试Spring 上下文加载过程中遇到的阻塞或死锁问题

IDEA单元测试一直转圈,阻塞,前置后置的方法都不执行,无任何输出 1.单元测试类 SpringBootTest(classes {BareMetalApplication.class}) RunWith(SpringRunner.class) public class K8sUserNfsStoreInitServiceImplTest {BeforeEachpublic…

国家力推!国家人工智能产业标准化指南

在科技日新月异的今天,人工智能(AI)作为推动社会进步和产业升级的关键力量,正以前所未有的速度改变着我们的世界。从自动驾驶到智能制造,从智慧医疗到金融科技,人工智能的触角已经深入到了经济社会的各个角…

三万字带你一遍跑通uer

三万字带你一遍跑通uer 参考文档 今天给大家介绍个非常强大的项目uer,集成了许多可以做自然语言的东西,效果的话也非常好,很适合企业级的应用! 1. 先将项目uer从github拉取下来(zip或git都ok) 2. 用pycha…

linux查看当前文件夹的剩余空间

要查看当前文件夹所在的文件系统的剩余空间,并以GB为单位显示,可以使用以下命令: df -BG .其中: B:用于指定块大小(block size)。你可以通过指定后缀来改变输出的单位,如K&#xf…

船舶雷达与导航系统选择7/8防水插座的原因分析

概述 船舶雷达与导航系统在现代航海中扮演着至关重要的角色,它们为船舶提供准确的导航信息,确保航行的安全和效率。在这些系统中,7/8防水插座的使用尤为重要,因为它们能够在恶劣的海上环境中提供稳定的电力和信号连接。接下来&am…

Finding Global Homophily in Graph Neural Networks When Meeting Heterophily

本文发表于:ICML22 推荐指数: #paper/⭐⭐⭐ 问题背景: 异配图的邻接矩阵难以确定,以及异配图的计算复杂度开销大 可行的解决办法:高通滤波多跳邻居,GPRGNN(pagerank一类,各阶邻居的权重不同,ACM-GCN(高低通滤波,H2GCN(应该复杂度很大&…

《梦醒蝶飞:释放Excel函数与公式的力量》8.8 STDEVP函数

8.8 STDEVP函数 STDEVP函数是Excel中用于计算总体数据的标准偏差的函数。标准偏差是统计学中的一个重要指标,用于衡量数据集中各数值偏离平均值的程度。总体标准偏差考虑了整个数据集,而不是样本。 8.8.1 函数简介 STDEVP函数用于返回总体数据的标准偏…

Infinitar链游新发展新机遇

区块链游戏市场在近年来经历了显著增长,吸引了大量的投资和关注。随着加密货币和NFT(非同质化代币)概念的普及,越来越多的投资者、游戏开发者和看到了区块链技术在游戏领域的应用潜力,纷纷涌入市场。区块链游戏的用户量…

LeetCode 算法:二叉树的最近公共祖先 III c++

原题链接🔗:二叉树的最近公共祖先 难度:中等⭐️⭐️ 题目 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点…

Jackson与Json、Json和各种Java数据类型的互相转化

jackson是什么 json是最常用的数据交换格式 Jackson是最流行的Json库 首先对于这种JSON序列化的库其实有非常多,比如我们熟悉的Gson,Fastjson等等,当然技术没有完全的好坏,但是从使用情况和社区生态等方面综合看来,Ja…

uni-app x 跨平台开发框架

目录 uni-app x 是什么 和Flutter对比 uts语言 uvue渲染引擎 组合式API的写法 选项式API写法 页面生命周期 API pages.json全局配置文件 总结 uni-app x 是什么 uni-app x,是下一代 uni-app,是一个跨平台应用开发引擎。 uni-app x 是一个庞…

A4-C四驱高防轮式巡检机器人

在当今数字化和智能化迅速发展的时代,旗晟智能带来了一款革命性的创新产品——A4-C四驱高防轮式巡检机器人。这款机器人以其卓越的性能和多功能性,为工业巡检领域带来了全新的解决方案。 一、产品亮点 1、四驱动力与高防护设计 四驱高防轮式巡检机器人…

el-table封装点击列筛选行数据功能,支持筛选,搜索,排序功能

数据少的话&#xff0c;可以前端实现&#xff0c;如果多的话&#xff0c;建议还是请求接口比较合理父组件&#xff1a; <template> <div class"home"> <!-- <img alt"Vue logo" src"../assets/logo.png"> <HelloWorld …

重塑通信边界,基于ZYNQ7000 FPGA驱动的多频段多协议软件无线电平台

01、产品概述 本平台是基于高性能ZYNQ-7000系列中的XC7Z045处理器构建的多频段多协议软件无线电解决方案&#xff0c;集成了AD9364芯片——一款业界领先的1x1通道RF敏捷收发器&#xff0c;为无线通信应用提供了强大支持。其存储架构包括2路高速4GB DDR3内存、1路32GB EMMC存储以…

springboot dynamic配置多数据源

pom.xml引入jar包 <dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.5.2</version> </dependency> application配置文件配置如下 需要主要必须配置…

ASUS/华硕飞行堡垒8 FX506L FX706L系列 原厂win10系统 工厂文件 带F12 ASUS Recovery恢复

华硕工厂文件恢复系统 &#xff0c;安装结束后带隐藏分区&#xff0c;一键恢复&#xff0c;以及机器所有驱动软件。 系统版本&#xff1a;Windows10 原厂系统下载网址&#xff1a;http://www.bioxt.cn 需准备一个20G以上u盘进行恢复 请注意&#xff1a;仅支持以上型号专用…