当前位置: 首页 > news >正文

android viewpager2 嵌套 recyclerview 手势冲突

老规矩直接上代码, 不分析:


import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import kotlin.math.abs
import kotlin.math.absoluteValue
import kotlin.math.sign/** Copyright 2019 The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**      http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*//*** Layout to wrap a scrollable component inside a ViewPager2. Provided as a solution to the problem* where pages of ViewPager2 have nested scrollable elements that scroll in the same direction as* ViewPager2. The scrollable element needs to be the immediate and only child of this host layout.** This solution has limitations when using multiple levels of nested scrollable elements* (e.g. a horizontal RecyclerView in a vertical RecyclerView in a horizontal ViewPager2).*/
class NestedScrollableHost : FrameLayout {constructor(context: Context) : super(context)constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)private var touchSlop = 0private var initialX = 0fprivate var initialY = 0fprivate val parentViewPager: ViewPager2?get() {var v: View? = parent as? Viewwhile (v != null && v !is ViewPager2) {v = v.parent as? View}return v as? ViewPager2}private val child: View? get() = if (childCount > 0) getChildAt(0) else nullinit {touchSlop = ViewConfiguration.get(context).scaledTouchSlop}private fun canChildScroll(orientation: Int, delta: Float): Boolean {val direction = -delta.sign.toInt()return when (orientation) {0 -> child?.canScrollHorizontally(direction) ?: false1 -> child?.canScrollVertically(direction) ?: falseelse -> throw IllegalArgumentException()}}override fun onInterceptTouchEvent(e: MotionEvent): Boolean {handleInterceptTouchEvent(e)return super.onInterceptTouchEvent(e)}private fun handleInterceptTouchEvent(e: MotionEvent) {val orientation = parentViewPager?.orientation ?: return// Early return if child can't scroll in same direction as parentif (!canChildScroll(orientation, -1f) && !canChildScroll(orientation, 1f)) {return}if (e.action == MotionEvent.ACTION_DOWN) {initialX = e.xinitialY = e.yparent?.requestDisallowInterceptTouchEvent(true)} else if (e.action == MotionEvent.ACTION_MOVE) {val dx = e.x - initialXval dy = e.y - initialYval isVpHorizontal = orientation == RecyclerView.HORIZONTAL// assuming ViewPager2 touch-slop is 2x touch-slop of childval scaledDx = dx.absoluteValue * if (isVpHorizontal) .5f else 1fval scaledDy = dy.absoluteValue * if (isVpHorizontal) 1f else .5fif (scaledDx > touchSlop || scaledDy > touchSlop) {if (isVpHorizontal == (scaledDy > scaledDx)) {// Gesture is perpendicular, allow all parents to interceptparent?.requestDisallowInterceptTouchEvent(false)} else {// Gesture is parallel, query child if movement in that direction is possibleif (canChildScroll(orientation, if (isVpHorizontal) dx else dy)) {// Child can scroll, disallow all parents to interceptparent?.requestDisallowInterceptTouchEvent(true)} else {// Child cannot scroll, allow all parents to interceptparent?.requestDisallowInterceptTouchEvent(false)}}}}}}
/** Copyright 2019 The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**      http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package androidx.viewpager2.integration.testappimport android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import android.widget.FrameLayout
import androidx.viewpager2.widget.ViewPager2
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
import kotlin.math.absoluteValue
import kotlin.math.sign/*** Layout to wrap a scrollable component inside a ViewPager2. Provided as a solution to the problem* where pages of ViewPager2 have nested scrollable elements that scroll in the same direction as* ViewPager2. The scrollable element needs to be the immediate and only child of this host layout.** This solution has limitations when using multiple levels of nested scrollable elements* (e.g. a horizontal RecyclerView in a vertical RecyclerView in a horizontal ViewPager2).*/
class NestedScrollableHost : FrameLayout {constructor(context: Context) : super(context)constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)private var touchSlop = 0private var initialX = 0fprivate var initialY = 0fprivate val parentViewPager: ViewPager2?get() {var v: View? = parent as? Viewwhile (v != null && v !is ViewPager2) {v = v.parent as? View}return v as? ViewPager2}private val child: View? get() = if (childCount > 0) getChildAt(0) else nullinit {touchSlop = ViewConfiguration.get(context).scaledTouchSlop}private fun canChildScroll(orientation: Int, delta: Float): Boolean {val direction = -delta.sign.toInt()return when (orientation) {0 -> child?.canScrollHorizontally(direction) ?: false1 -> child?.canScrollVertically(direction) ?: falseelse -> throw IllegalArgumentException()}}override fun onInterceptTouchEvent(e: MotionEvent): Boolean {handleInterceptTouchEvent(e)return super.onInterceptTouchEvent(e)}private fun handleInterceptTouchEvent(e: MotionEvent) {val orientation = parentViewPager?.orientation ?: return// Early return if child can't scroll in same direction as parentif (!canChildScroll(orientation, -1f) && !canChildScroll(orientation, 1f)) {return}if (e.action == MotionEvent.ACTION_DOWN) {initialX = e.xinitialY = e.yparent.requestDisallowInterceptTouchEvent(true)} else if (e.action == MotionEvent.ACTION_MOVE) {val dx = e.x - initialXval dy = e.y - initialYval isVpHorizontal = orientation == ORIENTATION_HORIZONTAL// assuming ViewPager2 touch-slop is 2x touch-slop of childval scaledDx = dx.absoluteValue * if (isVpHorizontal) .5f else 1fval scaledDy = dy.absoluteValue * if (isVpHorizontal) 1f else .5fif (scaledDx > touchSlop || scaledDy > touchSlop) {if (isVpHorizontal == (scaledDy > scaledDx)) {// Gesture is perpendicular, allow all parents to interceptparent.requestDisallowInterceptTouchEvent(false)} else {// Gesture is parallel, query child if movement in that direction is possibleif (canChildScroll(orientation, if (isVpHorizontal) dx else dy)) {// Child can scroll, disallow all parents to interceptparent.requestDisallowInterceptTouchEvent(true)} else {// Child cannot scroll, allow all parents to interceptparent.requestDisallowInterceptTouchEvent(false)}}}}}
}

相关文章:

android viewpager2 嵌套 recyclerview 手势冲突

老规矩直接上代码, 不分析: import android.content.Context import android.util.AttributeSet import android.view.MotionEvent import android.view.View import android.view.ViewConfiguration import android.view.ViewGroup import android.widg…...

依赖管理(go mod)

目录 各版本依赖管理的时间分布 一、GOPATH 1. GOROOT是什么 定义: 作用: 默认值: 是否需要手动设置: 查看当前的 GOROOT: 2. GOPATH:工作区目录 定义: 作用&#xff1a…...

Apple Vision Pro开发001-开发配置

一、Vision Pro开发硬件和软件要求 硬件要求软件要求 1、Apple Silicon Mac(M系列芯片的Mac电脑) 2、Apple vision pro-真机调试 XCode15.2及以上,调试开发和打包发布Unity开发者账号&&苹果开发者账号 二 、开启无线调试 1、Apple Vision Pro和Mac连接同…...

android 动画原理分析

一 android 动画分为app内的view动画和系统动画 基本原理都是监听Choreographer的doframe回调 二 app端的实现是主要通过AnimationUtils来实现具体属性的变化通过invilate来驱动 wms来进行更新。这个流程是在app进程完成 这里不是我分析的重点 直接来看下系统动画里面的本地动…...

Elasticsearch 6.8 分析器

在 Elasticsearch 中,分析器(Analyzer)是文本分析过程中的一个关键组件,它负责将原始文本转换为一组词汇单元(tokens)。 分析器由三个主要部分组成:分词器(Tokenizer)、…...

实验室资源调度系统:基于Spring Boot的创新

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统,它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等,非常…...

实验三:构建园区网(静态路由)

目录 一、实验简介 二、实验目的 三、实验需求 四、实验拓扑 五、实验任务及要求 1、任务 1:完成网络部署 2、任务 2:设计全网 IP 地址 3、任务 3:实现全网各主机之间的互访 六、实验步骤 1、在 eNSP 中部署网络 2、配置各主机 IP …...

3. SQL优化

SQL性能优化 在日常开发中,MySQL性能优化是一项必不可少的技能。本文以具体案例为主线,结合实际问题,探讨如何优化插入、排序、分组、分页、计数和更新等操作,帮助你实现数据库性能的飞跃。 一、索引设计原则 索引是MySQL优化的…...

web——upload-labs——第十一关——黑名单验证,双写绕过

还是查看源码, $file_name str_ireplace($deny_ext,"", $file_name); 该语句的作用是:从 $file_name 中去除所有出现在 $deny_ext 数组中的元素,替换为空字符串(即删除这些元素)。str_ireplace() 在处理时…...

AWS CLI

一、AWS CLI介绍 1、简介 AWS CLI(Amazon Web Services Command Line Interface)是一个命令行工具,它允许用户通过命令行与 Amazon Web Services(AWS)的各种云服务进行交互和管理。使用 AWS CLI,用户可以直接在终端或命令行界面中执行命令来配置、管理和自动化AWS资源,…...

springboot:责任链模式实现多级校验

责任链模式是将链中的每一个节点看作是一个对象,每个节点处理的请求不同,且内部自动维护一个下一节点对象。 当一个请求从链式的首段发出时,会沿着链的路径依此传递给每一个节点对象,直至有对象处理这个请求为止。 属于行为型模式…...

CentO7安装单节点Redis服务

本文目录 一、Redis安装与配置1.1 安装redis依赖1.2 上传压缩包并解压1.3 编译安装1.4 修改配置并启动1、复制配置文件2、修改配置文件3、启动Redis服务4、停止redis服务 1.5 redis连接使用1、 命令行客户端2、 图形界面客户端 一、Redis安装与配置 1.1 安装redis依赖 Redis是…...

FreeRTOS学习14——时间管理

时间管理 时间管理FreeRTOS 系统时钟节拍FreeRTOS 系统时钟节拍简介FreeRTOS 系统时钟节拍处理FreeRTOS 系统时钟节拍来源 FreeRTOS 任务延时函数vTaskDelay()vTaskDelayUntil() 时间管理 在前面的章节实验例程中,频繁地使用了 FreeRTOS 提供的延时函数&#xff0c…...

统⼀数据返回格式快速⼊⻔

为什么会有统⼀数据返回? 其实统一数据返回是运用了AOP(对某一类事情的集中处理)的思维。 优点: 1.⽅便前端程序员更好的接收和解析后端数据接⼝返回的数据。 2.降低前端程序员和后端程序员的沟通成本,因为所有接⼝都…...

Python学习------第十天

数据容器-----元组 定义格式,特点,相关操作 元组一旦定义,就无法修改 元组内只有一个数据,后面必须加逗号 """ #元组 (1,"hello",True) #定义元组 t1 (1,"hello") t2 () t3 tuple() prin…...

Win11 24H2新BUG或影响30%CPU性能,修复方法在这里

原文转载修改自(更多互联网新闻/搞机小知识): 一招提升Win11 24H2 CPU 30%性能,小BUG大影响 就在刚刚,小江在网上冲浪的时候突然发现了这么一则帖子,标题如下:基准测试(特别是 Time…...

element ui 走马灯一页展示多个数据实现

element ui 走马灯一页展示多个数据实现 element ui 走马灯一页展示多个数据实现 element ui 走马灯一页展示多个数据实现 主要是对走马灯的数据的操作,先看js处理 let list [{ i: 1, name: 1 },{ i: 2, name: 2 },{ i: 3, name: 3 },{ i: 4, name: 4 },]let newL…...

40分钟学 Go 语言高并发:Goroutine基础与原理

Day 03 - goroutine基础与原理 1. goroutine创建和调度 1.1 goroutine基本特性 特性说明轻量级初始栈大小仅2KB,可动态增长调度方式协作式调度,由Go运行时管理创建成本创建成本很低,可同时运行数十万个通信方式通过channel进行通信&#x…...

Figma插件指南:12款提升设计生产力的插件

在当今的设计领域,Figma已经成为许多UI设计师和团队的首选原型和数字设计软件。随着Figma的不断更新和插件库的扩展,这些工具极大地提升了设计工作的效率。本文将介绍12款实用的Figma插件,帮助你在UI设计中更加高效。 即时AI 即时AI利用先进…...

【K8S系列】Kubernetes集群资源管理与调度 深度分析

在现代微服务架构中,Kubernetes(K8s)作为容器编排平台,提供了强大的资源管理和调度能力。然而,随着应用规模的扩大和复杂性增加,如何高效地管理和调度集群资源成为一个关键挑战。本文将深入探讨 Kubernetes…...

【机器视觉】单目测距——运动结构恢复

ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛&#xf…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...

Android15默认授权浮窗权限

我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...