react-native-gesture-handler 手动手势实战:基于 `Gesture.Manual()` 的指针跟踪组件实现
移动开发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点击查看免费下载本指南围绕 RNGH2react-native-gesture-handler 2.x最受期待的新特性——**手动手势Manual Gesture与触摸事件Touch Events**展开以官方教程中跟踪屏幕上所有指针的完整示例为主线逐步讲解指针数据的存储与渲染数组上限 12 的缘由、触摸事件回调的编写以及如何通过manualActivation与StateManager改造现有手势。读完本文你将能够从零实现一个可跟踪全部触摸点、可自由控制激活/结束时机的手势组件并掌握在任意连续手势中读取原始触摸数据的方法。什么是手动手势在 RNGH2 之前手势处理完全由平台原生识别器主导开发者只能在预设手势Tap、Pan、Pinch 等的框架内工作难以实现完全自定义的识别逻辑。手动手势Gesture.Manual()将控制权交还给开发者它本身不做任何识别只负责把原始触摸数据通过事件回调暴露给你由你在回调中自行决定何时激活、何时结束。官方教程用一个跟踪屏幕上所有指针的示例演示这一能力屏幕上每个触摸点显示为一个圆球手势激活后圆球变为红色并放大抬起手指后圆球消失。这一示例由 7 个步骤组成核心文件位于 packages/docs-gesture-handler/versioned_docs/version-2.x/guides/manual-gestures/index.md 及其_steps/目录中。指针数据的存储与渲染第 3 步的核心骨架教程的第 3 步即本指南的主体见 step3.md解决了整个示例的数据载体问题如何存放指针信息、如何把它们渲染到屏幕上。import { Gesture, GestureDetector } from react-native-gesture-handler; export default function Example() { const trackedPointers: Animated.SharedValuePointer[] []; const active useSharedValue(false); for (let i 0; i 12; i) { trackedPointers[i] useSharedValue Pointer { visible: false, x: 0, y: 0, }; } const gesture Gesture.Manual(); return ( GestureDetector gesture{gesture} Animated.View style{{ flex: 1 }} {trackedPointers.map((pointer, index) ( PointerElement pointer{pointer} active{active} key{index} / ))} /Animated.View /GestureDetector ); }这段代码包含三个关键设计值得逐一拆解1. 数组大小固定为 12对应 RNGH 跟踪触摸的上限。教程原文明确说明12 是 RNGH 会跟踪的最大触摸数量the maximum number of touches that RNGH will track。之所以在渲染层预留 12 个槽位是因为后续触摸事件回调里直接用touch.id作为数组下标写入数据见第 4 步数组必须覆盖所有可能出现的id取值否则会出现越界写入或渲染缺项。2. 每个指针用Animated.SharedValuePointer存储。这里用到了react-native-reanimated的共享值。配合第 2 步的PointerElement组件指针的位置x/y、可见性visible都成为可在 worklet 中直接读写的响应式数据任何触摸回调里的更新都能驱动 UI 动画而无需触发 React 重渲染。3. 手势与视图通过GestureDetector绑定。Gesture.Manual()创建的手势实例传入GestureDetector包裹整个Animated.View。所有触摸事件都在该视图区域内被捕获。配套组件PointerElement第 2 步渲染层需要一个把共享值翻译成视图样式的组件。教程第 2 步step2.md实现的PointerElement接收两个共享值pointer指针数据与active手势是否已激活。import { StyleSheet } from react-native; import Animated, { useAnimatedStyle, useSharedValue, } from react-native-reanimated; function PointerElement(props: { pointer: Animated.SharedValuePointer, active: Animated.SharedValueboolean, }) { const animatedStyle useAnimatedStyle(() ({ transform: [ { translateX: props.pointer.value.x }, { translateY: props.pointer.value.y }, { scale: (props.pointer.value.visible ? 1 : 0) * (props.active.value ? 1.3 : 1), }, ], backgroundColor: props.active.value ? red : blue, })); return Animated.View style{[styles.pointer, animatedStyle]} /; } // ... const styles StyleSheet.create({ pointer: { width: 60, height: 60, borderRadius: 30, backgroundColor: red, position: absolute, marginStart: -30, marginTop: -30, }, });要点说明scale由两个因子相乘visible为false时缩放为 0圆球消失手势激活时再放大到 1.3 倍颜色在蓝未激活与红已激活之间切换与教程描述的未激活蓝色、激活红色且稍大完全对应圆球为 60×60、圆角 30 的绝对定位视图marginStart/marginTop取负值使圆心对准指针坐标这正是第 1 步 Pointer 接口visible: boolean; x: number; y: number;被消费的方式。触摸事件回调完成手势第 4–7 步有了存储与渲染骨架接下来用触摸事件回调填充数据。手势对象上可用链式 API 注册四个触摸事件处理器其类型定义可在源码 gesture.ts 中确认type TouchEventHandlerType ( event: GestureTouchEvent, stateManager: GestureStateManagerType ) void;即每个处理器都收到GestureTouchEvent事件与一个stateManager前者携带触摸数据后者用于修改手势状态。onTouchesDown按下时记录并激活第 4 步const gesture Gesture.Manual().onTouchesDown((e, manager) { for (const touch of e.changedTouches) { trackedPointers[touch.id].value { visible: true, x: touch.x, y: touch.y, }; } if (e.numberOfTouches 2) { manager.activate(); } });事件对象e提供changedTouches本次变化的触摸数组与numberOfTouches当前屏幕上的触摸总数。这里把每个新按下的指针置为可见并写入坐标同时约定至少两个手指时激活手势——激活操作由manager.activate()完成。onTouchesMove移动时更新坐标第 5 步const gesture Gesture.Manual() ... .onTouchesMove((e, _manager) { for (const touch of e.changedTouches) { trackedPointers[touch.id].value { visible: true, x: touch.x, y: touch.y, }; } })逻辑与按下时一致遍历changedTouches用touch.id定位对应共享值并更新坐标。由于共享值在 worklet 中同步写入指针圆球会随手指平滑移动。onTouchesUp抬起时隐藏并结束第 6 步const gesture Gesture.Manual() ... .onTouchesUp((e, manager) { for (const touch of e.changedTouches) { trackedPointers[touch.id].value { visible: false, x: touch.x, y: touch.y, }; } if (e.numberOfTouches 0) { manager.end(); } })抬起手指时把对应指针设为不可见当numberOfTouches归零所有手指都已离开屏幕时调用manager.end()结束手势。关于onTouchesCancelled教程明确说明本例未处理该回调因为在最基础的场景下不期望它发生但同时强调——当它被触发时你应当清除关于被取消指针大多数情况下是全部活动指针的数据否则会出现手指已离开但圆球残留的脏状态。onStart / onEnd状态变化驱动 UI第 7 步const gesture Gesture.Manual() ... .onStart(() { active.value true; }) .onEnd(() { active.value false; });onStart在手势激活时触发onEnd在结束时触发。这里只翻转active共享值PointerElement的useAnimatedStyle会自动响应实现激活变红变大、结束恢复蓝色的视觉效果。完整的 Pointer 接口第 1 步整个数据链路的起点是第 1 步定义的接口interface Pointer { visible: boolean; x: number; y: number; }至此 7 步全部打通接口定义数据形状 →PointerElement消费数据渲染 → 第 3 步的数组提供 12 个槽位 → 四个触摸回调写入/清除数据 →manager.activate()/manager.end()控制状态机。正如教程总结所言手动手势用起来很简单但它能实现此前 RNGH 无法完成的场景。源码视角触摸回调如何驱动状态机manager即GestureStateManager的四个方法在源码 gestureStateManager.ts 中均有明确实现它们通过_setGestureStateSync/_setGestureStateAsync将目标状态同步给原生侧方法对应状态用途begin()State.BEGAN手势开始过渡可选的中间态activate()State.ACTIVE正式激活手势触发onStartfail()State.FAILED判定手势失败不会进入激活end()State.END正常结束手势触发onEnd这正是第 4/6 步中activate()/end()调用的底层实现状态一旦设置原生侧手势状态机随即推进进而驱动onStart/onEnd等状态回调。因此手动手势的本质是触摸事件负责收集数据StateManager负责决策状态两者分离让识别逻辑完全可控。修改现有手势触摸事件 manualActivation教程在示例之外还给出一个重要扩展不必为每个自定义场景从零实现手势。所有手势不只Manual都支持触摸事件回调你可以从任意手势中提取比基础事件更细的触摸信息同时所有连续手势都新增了manualActivation修饰符开启后手势不再自动激活激活时机完全由你通过StateManager决定。这一配置项可在 gesture.ts 的BaseGestureConfig中确认。教程用长按后拖拽drag after long press这一高频需求举例说明组合用法// 思路示意Pan 手势不再自动激活 const pan Gesture.Pan().manualActivation(true); // 在触摸/状态回调中自行判定 // - 若用户过早拖动未达到长按时长调用 manager.fail() 使手势失败 // - 若满足长按条件调用 manager.activate() 让 Pan 接管后续拖动。manualActivation的意义在于它把何时开始拖动的判断从原生识别器移交给业务代码从而让按住停顿—开始拖动这类需要自定义时序的交互成为可能。这一能力同样来自 RNGH2 的手动激活机制与上文GestureStateManager的fail/activate直接配套。小结数据层用Animated.SharedValuePointer[]定长数组12 个槽位承载指针信息touch.id直接作为下标保证读写一致渲染层PointerElement通过useAnimatedStyle将共享值映射为位移、缩放与颜色全部动画在 UI 线程完成控制层onTouchesDown/Move/Up/Cancelled负责维护数据manager.activate()/end()/fail()负责推进状态机复用层任何连续手势均可附加触摸回调与manualActivation(true)配合StateManager实现长按后拖拽等定制交互。若需进一步查看该教程的完整编排与全部步骤代码可阅读 manual-gestures 教程入口触摸事件回调的类型定义与状态管理器实现分别在 gesture.ts 与 gestureStateManager.ts 中可作为继续深入的手册。赞分享移动开发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 手动手势Manual Gesture实战构建多点触控指针追踪容器组件react native gesture handler 手动手势Manual Gesture实战构建多点触控指针追踪容器组件 本指南聚焦 react n移动开发UI组件React Native Gesture Handler 手册手势Manual Gesture触控收尾用 onTouchesUp 完成指针跟踪与手势结束React Native Gesture Handler 手册手势Manual Gesture触控收尾用 onTouchesUp 完成指针跟踪与手势结束移动开发UI组件react-native-gesture-handler 手动手势实战onTouchesMove 触摸移动事件解析与多点指针追踪react native gesture handler 手动手势实战onTouchesMove 触摸移动事件解析与多点指针追踪 导读 本文以 react n移动开发UI组件上一篇NanoMQ终极指南3步构建高性能边缘MQTT消息服务器下一篇3D打印螺纹优化告别断裂烦恼的FDM工艺解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Hazelcast Scheduled 与 Durable Executor 服务指标统计的设计与实现

Hazelcast Scheduled 与 Durable Executor 服务指标统计的设计与实现

缓存KV存储消息队列流处理后端 【免费下载链接】hazelcast Hazelcast is a unified real-time data platform combining stream processing with a fast data store, allowing customers to act instantly on data-in-motion for real-time insights. 项目地址: htt…

2026/10/11 4:37:35 阅读更多 →
微信小程序+SpringBoot竞赛管理系统实战指南

微信小程序+SpringBoot竞赛管理系统实战指南

简介:本资源是一套面向计算机专业本科生的毕业设计实战项目,聚焦大学生科技竞赛全流程数字化管理需求,采用微信小程序Spring Boot前后端分离架构,适用于Java全栈开发学习与课程设计参考。资源包共1338个文件,涵盖131个…

2026/10/12 23:43:53 阅读更多 →
JavaWeb电子商城系统部署与数据一致性实战指南

JavaWeb电子商城系统部署与数据一致性实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 23:55:35 阅读更多 →

最新新闻

考研数据结构复试高频考点、手写代码与面试应对策略

考研数据结构复试高频考点、手写代码与面试应对策略

初试成绩出来之后,很多同学会陷入一种“不知道该干什么”的状态。刷题吧,好像复试不考这么细;看论文吧,又不知道从哪看起;真要准备机试,又发现手生的厉害。我自己当年备考“考研数据结构复试题目整理”的时…

2026/10/14 4:25:51 阅读更多 →
考虑主从配电网分布式优化的ADMM算法Matlab实现与串并行对比

考虑主从配电网分布式优化的ADMM算法Matlab实现与串并行对比

最近在推进一个关于主从配电网分布式优化控制的课题时,核心目标是用交替方向乘子法(ADMM)把主网和多个配电子网之间的协同优化拆开做,整个算法在Matlab里落地,并对比了串行和并行两种执行机制下的收敛行为。从模型搭建…

2026/10/14 4:25:51 阅读更多 →
2026 AI 论文工具排行榜|按「国内毕业论文适配度」打分,适合盲审抽检环境

2026 AI 论文工具排行榜|按「国内毕业论文适配度」打分,适合盲审抽检环境

前言 很多海外 AI 工具在国外学术写作里表现亮眼,但拿到国内本科、硕士毕业论文场景,就会水土不服。国内高校论文有一套独立规则:GB/T7714 参考文献格式、固定 Word 排版规范、AI 痕迹检测、参考文献溯源抽查、逻辑盲审。 本次排行榜不再看通…

2026/10/14 4:25:51 阅读更多 →
一次GC频繁问题排查:从JFR到代码优化的完整实践

一次GC频繁问题排查:从JFR到代码优化的完整实践

大概一个多月前,我接到一条让我头疼不已的告警:某个订单查询接口的 P99 延迟从平时的 80ms 一路飙到 800ms 以上,CPU 使用率每隔几分钟就像过山车一样冲到接近 100%。一开始我照例查了流量、数据库慢查询、第三方依赖,全都没有异常…

2026/10/14 4:25:51 阅读更多 →
pdf.js在线查看PDF工具:渲染原理、避坑指南与性能优化实践

pdf.js在线查看PDF工具:渲染原理、避坑指南与性能优化实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 4:25:51 阅读更多 →
Dropout 正则化原理与实战:从过拟合到泛化能力提升

Dropout 正则化原理与实战:从过拟合到泛化能力提升

1. 为什么一个"随手关掉神经元"的操作能成为深度学习的基石第一次在代码里写下nn.Dropout(p0.5)的时候,我其实没太当回事——不就是训练时随机扔掉一半神经元嘛,听起来像个正则化的小把戏。直到有一次复现一篇图像分类论文,模型在训…

2026/10/14 4:24:51 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →