ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

PanGestureHandler 完全指南:在 React Native 中实现拖拽、平移与多指手势跟踪

PanGestureHandler 完全指南:在 React Native 中实现拖拽、平移与多指手势跟踪 移动开发UI组件【免费下载链接】react-native-gesture-handlerDeclarative API exposing platform native touch and gesture system to React Native.项目地址https://gitcode.com/gh_mirrors/re/react-native-gesture-handler点击查看免费下载导读本文围绕 react-native-gesture-handler 的PanGestureHandler1.x 版本 API系统讲解连续型手势识别原理、自定义激活/失败判定条件、多指平移的平台差异与统一方案以及完整的事件数据字段。你将学会用声明式组件在 iOS 与 Android 上实现可复制的拖拽交互并理解minDist、activeOffset、failOffset等配置的底层判定逻辑为升级到 v3 的Gesture.Pan()打下基础。概述连续手势的识别与跟踪PanGestureHandler是一个连续型continuous手势处理器用于识别平移拖拽手势并持续跟踪其移动轨迹。当手指放到屏幕上并移动一定的初始距离后处理器进入 ACTIVE 状态参见 state 文档通过配置可以指定最小初始移动距离、仅检测垂直/水平方向平移以及激活所需的触点数支持多指滑动在手势进行中onGestureEvent回调会持续触发提供从起点开始的 XY 位移以及当前瞬时速度等关键信息。实现层面该处理器在 iOS 基于UIPanGestureRecognizer在 Android 基于 PanGestureHandler.kt。在当前仓库中对应 iOS 的具体实现位于 RNPanHandler.m其内部使用了一个名为RNBetterPanGestureRecognizer的UIPanGestureRecognizer子类来承载自定义激活判定逻辑。注意在仓库源码中如 PanGestureHandler.tsPanGestureHandler组件已被标记为deprecated官方推荐使用新版 APIGesture.Pan()。但 1.x 文档中的这套属性与事件数据模型在新版Gesture.Pan()中依然原样保留理解本页内容可以直接迁移到 v3 用法。自定义激活判定Custom activation criteriaPanGestureHandler暴露了一系列属性用于定制处理器在识别手势时的激活activate与失败fail判定标准。其核心规则是当设置了多个判定属性时PanGestureHandler要求全部条件同时满足才会成功激活只要任意一个条件被突破overstepped就会判定识别失败。规则示例若同时设置minDeltaX与minDeltaY各 20则手指必须在 X 与 Y 两个轴上都移动 20 点处理器才会激活若同时设置maxDeltaX与maxDeltaY各 20以及minDist23当手指沿 X 轴移动 20 点、沿 Y 轴移动 0 点时即便 Y 轴方向仍在允许范围内处理器也会判定失败。这一“全部满足才激活、任一越界即失败”的语义在 Android 侧由 PanGestureHandler.kt 的shouldActivate()与shouldFail()两个方法直接实现在 iOS 侧则由 RNPanHandler.m 的shouldActivateUnderCustomCriteria/shouldFailUnderCustomCriteria完成对应判定。可以看到两个平台都采用“逐条件短路判断”的方式任一条件命中即返回YES/true。多指平移处理Multi touch pan handling如果你的应用依赖多指平移需要了解平台默认行为的差异以及在必要时如何统一。差异核心在于事件中位移translation属性的计算方式iOS默认行为屏幕上放置多根手指时系统会视作只有一个指针其位置为所有指针的质心average position / center of mass。这一行为同样适用于许多原生组件即使它们并非主要用于多指交互例如UIScrollView。Android / 原生组件如 scroll view、pager views、drawers的默认行为不同不再把“所有手指的质心”作为主导指针而是取最后放置的那根手指作为主导指针。这一行为可以通过 Android 上的avgTouches标志修改。从 Android 实现可以看到PanGestureHandler.kt 的源码注释明确说明了这一差异Android 上多指平移时默认只考虑最后放置的指针而 iOS 会将各指针位置求平均averageTouches属性可将 Android 行为切换为 iOS 的“质心”模式。值得注意在 Android 和 iOS 上当额外的手指放到屏幕上时translation 属性不会受影响——即使被跟踪指针的位置可能发生变化。因此大多数情况下可以安全依赖 translation因为它只反映“与屏幕上手指数量无关、且数量随时间变化也不影响”的移动量。若你需要跟踪“质心”虚拟指针、并希望在手指数量变化时也纳入其变化可以使用事件中提供的相对位置或绝对位置即x/y相对视图或absoluteX/absoluteY相对根视图。属性PropertiesPanGestureHandler首先继承基础 handler 类的公共属性集合如enabled、shouldCancelWhenOutside、simultaneousHandlers、waitFor、hitSlop、onGestureEvent、onHandlerStateChange等。以下是PanGestureHandler特有的属性minDist手指或多根手指在处理器 激活 前需要移动的最小距离以点points为单位。Android 上默认取系统的scaledTouchSlop值见 PanGestureHandler.ktminDist平方后参与距离判定distSq minDist * minDist。iOS 侧在 RNPanHandler.m 中同样以平方形式存储minDistSq dist * dist与矢量长度平方比较。minPointers处理器 激活 前需要在屏幕上放置的手指数量应为大于或等于 0 的整数。Android 默认值为1见 PanGestureHandler.kt。maxPointers当屏幕上放置的手指达到给定数量、而处理器尚未激活时它会判定识别失败。应为大于或等于 0 的整数。Android 默认值为10见 PanGestureHandler.kt。activeOffsetX沿 X 轴单位点的激活偏移范围手指在此范围内移动不会激活处理器移出该范围即激活。范围可以以数组或单个数字给出。若以数组给出第一个值必须≤ 0第二个值必须≥ 0。若只给出单个数字p当p ≥ 0时使用范围(-inf, p)否则p 0使用范围(-p, inf)。activeOffsetY沿 Y 轴单位点的激活偏移范围语义与activeOffsetX完全一致范围内不激活移出即激活。数组/单数字的取值规则同上。failOffsetY当手指沿 Y 轴移出此范围单位点且处理器尚未激活时会判定识别失败。数组/单数字的取值规则同上。failOffsetX当手指沿 X 轴移出此范围单位点且处理器尚未激活时会判定识别失败。数组/单数字的取值规则同上。avgTouches仅 Android是否启用“多指质心”平移计算模式。默认false取最后放置的手指为主导指针设为true后切换为 iOS 式的“所有手指平均位置”模式。参见上文多指平移处理。enableTrackpadTwoFingerGesture仅 iOS启用受支持设备例如带触控板的 iPad上的双指手势。若未启用手势需要“点击 拖拽”才能触发启用后在触控板上用两根手指滑动同样会触发该手势。对应 iOS 实现将配置映射到allowedScrollTypesMask见 RNPanHandler.m启用时设为UIScrollTypeMaskAll。类型定义与数组转换从源码 PanGestureHandler.ts 可以确认PanGestureHandler还支持以下在 1.x 文档未逐一列出的扩展属性minVelocity、minVelocityX、minVelocityY最小速度阈值与activateAfterLongPress长按后激活延迟Android 单位为毫秒、iOS 单位为秒。在 JS 层数组形式的activeOffsetX/Y、failOffsetX/Y会被拆分为activeOffsetXStart/activeOffsetXEnd等内部原生属性见 transformPanGestureHandlerProps再传递给原生端。同时 validatePanGestureHandlerProps 会在__DEV__下校验数组首元素必须 ≤ 0、次元素必须 ≥ 0且minDist与 offset 系列属性不可混用会抛出明确的开发期错误。事件数据Event dataPanGestureHandler的事件载荷首先包含基础 handler 类的公共事件属性如state、numberOfPointers。以下是PanGestureHandler特有的事件字段translationX平移手势沿 X 轴从手势开始以来累积的位移单位为点。Android 侧的实时计算公式为lastX - startX offsetX见 PanGestureHandler.kt其中offset用于在手指数量增减时保持位移连续。translationY平移手势沿 Y 轴从手势开始以来累积的位移单位为点。计算逻辑同translationX。velocityX当前时刻平移手势沿 X 轴的瞬时速度单位为点/秒。Android 侧通过VelocityTracker以 1000ms 窗口计算见 PanGestureHandler.kt。velocityY当前时刻平移手势沿 Y 轴的瞬时速度单位为点/秒。x指针手指或存在多指时的主导指针当前位置相对处理器所挂载视图的 X 坐标单位为点。y指针当前位置相对处理器所挂载视图的 Y 坐标单位为点。absoluteX指针当前位置**相对根视图root view**的 X 坐标单位为点。当原视图可能因手势本身发生变换transform时推荐使用absoluteX而非x。absoluteY指针当前位置相对根视图的 Y 坐标单位为点。同样推荐在视图被变换时使用absoluteY而非y。在 TypeScript 层以上字段由 PanGestureHandlerEventPayload 完整定义额外还包括可选的手写笔数据stylusDataiPad Apple Pencil 场景。示例用PanGestureHandler实现可拖拽圆形下面是一个经典的“可拖拽圆圈”示例原始示例来自 draggable 示例仓库中该示例还展示了利用onHandlerStateChange在每次手势结束后记录lastOffset并重设translateX/Y的累积位移技巧const circleRadius 30; class Circle extends Component { _touchX new Animated.Value(windowWidth / 2 - circleRadius); _onPanGestureEvent Animated.event([{ nativeEvent: { x: this._touchX } }], { useNativeDriver: true, }); render() { return ( PanGestureHandler onGestureEvent{this._onPanGestureEvent} Animated.View style{{ height: 150, justifyContent: center, }} Animated.View style{[ { backgroundColor: #42a5f5, borderRadius: circleRadius, height: circleRadius * 2, width: circleRadius * 2, }, { transform: [ { translateX: Animated.add( this._touchX, new Animated.Value(-circleRadius) ), }, ], }, ]} / /Animated.View /PanGestureHandler ); } }要点说明PanGestureHandler包裹目标视图onGestureEvent通过Animated.event将事件的x字段直接接入Animated.Value配合useNativeDriver: true实现原生驱动的流畅位移由于事件基于“从手势开始累积的位移”拖拽类场景也可直接取translationX/translationY如仓库 draggable 示例 的做法并在onHandlerStateChange中于手势结束时oldState State.ACTIVE累加偏移量从而支持连续多次拖拽。常见问题与最佳实践minDist与 offset 系列属性不可混用源码校验见 PanGestureHandler.ts会在开发期抛出错误提示使用activeOffsetX/Y或failOffsetX/Y代替请遵循提示调整配置。offset 数组的边界约束activeOffsetX、activeOffsetY、failOffsetX、failOffsetY的数组形式要求首元素 ≤ 0、次元素 ≥ 0否则同样会在开发期报错。速度激活若希望“快速滑动即激活、慢速拖动不激活”可配置minVelocity/minVelocityX/minVelocityY单位点/秒Android 与 iOS 实现均以绝对值比较速度见 PanGestureHandler.kt 与 RNPanHandler.m。多指场景的位移稳定性translation 不会因手指数量增减而跳变原生端通过 offset 机制补偿若需要跟踪“质心”位置变化请改用x/y或absoluteX/absoluteY。升级到 v3PanGestureHandler已被标记为废弃新代码应使用Gesture.Pan()新版 API 中的GestureDetector其配置项minDist、activeOffsetX/Y、failOffsetX/Y、minPointers、maxPointers等与事件字段translationX/Y、velocityX/Y、x/y、absoluteX/Y保持一致迁移成本很低。延伸阅读基础 handler 公共属性与事件enabled、hitSlop、simultaneousHandlers、waitFor、onGestureEvent、onHandlerStateChange等公共配置。Handler 状态文档BEGAN、ACTIVE、FAILED、CANCELLED等状态的含义与流转。可拖拽完整实现draggable 示例原生实现Android PanGestureHandler.kt 与 iOS RNPanHandler.m类型定义PanGestureHandler.ts 与 PanGestureHandlerEventPayload赞分享移动开发UI组件【免费下载链接】react-native-gesture-handlerDeclarative API exposing platform native touch and gesture system to React Native.项目地址https://gitcode.com/gh_mirrors/re/react-native-gesture-handler点击查看免费下载相关推荐react-native-gesture-handler PanGestureHandler 拖拽手势完整指南激活准则、事件数据与多指平移react native gesture handler PanGestureHandler 拖拽手势完整指南激活准则、事件数据与多指平移 本篇技术指南围绕移动开发UI组件终极免费方案VLC for Android如何彻底解决你的移动视频播放难题终极免费方案VLC for Android如何彻底解决你的移动视频播放难题 你是否曾因手机无法播放下载的电影而烦恼是否遇到过网络视频卡顿、字幕不同步的问题音视频移动开发Ice如何 5 分钟整理 Mac 菜单栏隐藏、拖拽、美化一次搞定Ice如何 5 分钟整理 Mac 菜单栏隐藏、拖拽、美化一次搞定 Ice 是一款面向 macOS 的开源菜单栏管理工具负责隐藏、重排和美化菜单栏图标支持桌面应用上一篇5分钟搭建新闻级直播系统MediaMTX流媒体技术全解析下一篇如何快速开发text-generation-inference自定义后端扩展支持新模型的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表