
移动开发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 旧版v2连续手势continuous gesture中唯一的通用配置项manualActivation。该属性让手势即使满足自身的激活条件也不会自动激活而是交由开发者通过GestureStateManager状态管理器手动掌控状态机流转。读完本文你将掌握manualActivation的类型签名、生效范围、底层实现原理以及如何配合状态管理器实现“由业务逻辑决定何时激活手势”的完整实战方案。一、定位连续手势的通用配置在 react-native-gesture-handler 的旧版v2手势体系中文档将手势划分为连续手势continuous gestures与离散手势discrete gestures两大类。连续手势包括 Pan平移、Pinch捏合、Rotation旋转、LongPress长按、Fling快速滑动等它们会在一个持续的时间窗口内反复产生更新事件。根据 base-continuous-gesture-config.md 的说明所有连续手势共有的配置属性只有一个即manualActivationProperties common to all continuous gestures:manualActivation(value: boolean)作用当值为true时即使手势已经满足自身的激活条件例如 Pan 手势检测到手指发生了位移、LongPress 手势满足了长按时长该 handler 也不会自行激活。配合对象此时需要借助 state manager状态管理器来手动操作手势的状态。简单来说manualActivation把“激活决策权”从手势自身的判定逻辑中剥离出来交还给开发者是实现“自定义激活条件”的标准入口。1.1 与旧版事件回调的关联从源码中的类型定义可以确认该属性的真实身份。在 gestureHandlerCommon.ts 中baseGestureHandlerWithDetectorProps显式列出了export const baseGestureHandlerWithDetectorProps [ ...commonProps, needsPointerData, manualActivation, ];也就是说manualActivation是传给底层 handler 的探测器detector级属性与needsPointerData并列而非普通的事件回调。二、类型签名与取值范围2.1 旧版v2中的布尔签名旧版文档给出的签名为manualActivation(value: boolean)在 gesture.ts 的BaseGestureConfig中同样以布尔字段存在export interface BaseGestureConfig extends CommonGestureConfig, Recordstring, unknown { ref?: React.MutableRefObjectGestureType | undefined; requireToFail?: GestureRef[]; simultaneousWith?: GestureRef[]; blocksHandlers?: GestureRef[]; needsPointerData?: boolean; manualActivation?: boolean; runOnJS?: boolean; testId?: string; cancelsTouchesInView?: boolean; }类型boolean可选缺省时默认不启用。默认值false即手势按默认的激活条件自动激活。2.2 新版v3中的扩展签名在 v3 的新 API 中manualActivation被扩展为可以接收 SharedValue从而允许在 Reanimated 的工作线程worklet中动态切换manualActivation: boolean | SharedValueboolean;对应类型定义位于 ConfigTypes.ts 的CommonGestureConfig中export type CommonGestureConfig { disableReanimated?: boolean | undefined; useAnimated?: boolean | undefined; testID?: string | undefined; } WithSharedValue { runOnJS?: boolean | undefined; enabled?: boolean | undefined; shouldCancelWhenOutside?: boolean | undefined; hitSlop?: HitSlop | NormalizedHitSlop | undefined; activeCursor?: ActiveCursor | undefined; mouseButton?: MouseButton | undefined; cancelsTouchesInView?: boolean | undefined; cancelsJSResponder?: boolean | undefined; manualActivation?: boolean | undefined; }, ActiveCursor | MouseButton ;提示本文以旧版legacy gestures即 v2 API为主体展开但manualActivation的核心语义在两个版本中保持一致。三、底层实现manualActivation 是如何阻止自动激活的为了准确理解该属性的行为需要查看其在 Web 平台手势处理器的实现。在 GestureHandler.ts 中manualActivation被保存在处理器实例上private manualActivation: boolean false;并在配置更新时被写入if (config.manualActivation ! undefined) { this.manualActivation config.manualActivation; }关键逻辑体现在activate(force false)方法中public activate(force false) { if ( (this.manualActivation ! true || force) this.state State.BEGAN ) { this.delegate.onActivate(); this.moveToState(State.ACTIVE); } }这段代码说明了两点事实当manualActivation为true时手势在 BEGAN 状态下即使收到激活信号也不会自动迁移到 ACTIVE 状态除非传入force参数GestureStateManager的手动激活走的是带force语义的路径因此能够绕过这一限制这正是“用状态管理器手动控制状态”得以成立的根本原因。从源码结构看iOS/Android 原生侧同样维护manualActivation语义各平台行为保持一致该属性只影响“自动激活”这一个环节不影响手势的识别与事件分发。四、状态管理器manualActivation 的必配搭档启用manualActivation: true之后手势的生命周期就必须由GestureStateManager来驱动。旧版文档 state-manager.md 给出如下说明GestureStateManagerallows you to manually control the state of the gestures. Please note thatreact-native-reanimatedis required to use it, since it allows for synchronously executing methods in worklets.需要特别注意的是使用GestureStateManager依赖react-native-reanimated因为它需要在 worklet 中同步执行状态操作方法。4.1 状态管理器的四个核心方法旧版GestureStateManager提供以下方法均以handlerTag为参数返回void方法作用生效前提 / 边界条件begin()将手势迁移到BEGAN状态手势尚未激活或结束时调用有效否则无效activate()将手势迁移到ACTIVE状态手势未处于 active 且未结束时有效若与更高优先级手势构成互斥关系激活会被推迟到对方失败之后end()将手势迁移到END状态手势尚未结束时有效fail()将手势迁移到FAILED状态手势尚未结束时有效4.2 handlerTag 的两种获取方式状态管理基于handlerTag进行。旧版文档给出了两种典型场景场景一在手势定义内部操作自身状态从事件参数中直接取得handlerTag例如在onTouchesDown中立即激活一个 LongPressconst longPress Gesture.LongPress() .onTouchesDown((e) { GestureStateManager.activate(e.handlerTag); }) .onActivate(() { console.log(LongPress activated!); });场景二在外部控制其他手势的生命周期从已创建的手势对象上读取handlerTag例如让一次长按去激活一个 Pan 手势const pan Gesture.Pan().onActivate(() { console.log(Pan activated!); }); const longPress Gesture.LongPress().onActivate(() { GestureStateManager.activate(pan.handlerTag); });注意手势只有在接收过触摸事件即已开始之后才能被激活这一点在 v3 文档的 state-manager 中有明确提示The gestures can only be activated after they have begun旧版同样适用。五、综合实战用 manualActivation 实现“自定义激活条件”的 Pan 手势将manualActivation与状态管理器结合最常见的需求是在 Pan 手势原本会自动激活的情况下改为由自定义业务逻辑决定何时激活。下面是一个可直接运行的示例蓝色方块上的 Pan 手势设置了manualActivation: true因此仅仅拖动它并不会激活手势开发者必须主动调用GestureStateManager才能让它进入 ACTIVE 状态import { View } from react-native; import { GestureDetector, GestureHandlerRootView, GestureStateManager, Gesture, } from react-native-gesture-handler; export default function App() { const pan Gesture.Pan() .manualActivation(true) .onTouchesDown((e) { // 由业务逻辑决定例如当满足自定义条件时才激活 GestureStateManager.activate(e.handlerTag); }) .onActivate(() { console.log(Pan gesture activated); }); return ( GestureHandlerRootView style{styles.container} GestureDetector gesture{pan} View style{styles.box} / /GestureDetector /GestureHandlerRootView ); } const styles { container: { flex: 1, alignItems: center, justifyContent: space-around, }, box: { width: 150, height: 150, backgroundColor: blue, }, };5.1 更进一步完全自定义的 Manual 手势如果连“识别与事件数据”都想完全自定义可以改用Gesture.Manual()见 use-manual-gesture.mdx。它本身没有任何激活条件与事件数据所有状态切换都必须由状态管理器驱动且在所有指针离开屏幕时也不会失败。例如下面的多点跟踪示例在第二个手指落下时激活手势在最后一个手指抬起时结束const gesture Gesture.Manual() .onTouchesDown((e) { // 更新各指针位置…… if (e.numberOfTouches 2) { GestureStateManager.activate(e.handlerTag); } }) .onTouchesMove((e) { // 更新移动指针的位置…… }) .onTouchesUp((e) { if (e.numberOfTouches 0) { GestureStateManager.deactivate(e.handlerTag); } }) .onActivate(() { active.value true; }) .onDeactivate(() { active.value false; });可以看到manualActivation与Gesture.Manual()是两种互补的“手动控制”手段manualActivation: true保留原生手势Pan、Pinch、Rotation 等的识别与事件数据仅关闭自动激活Gesture.Manual()连识别逻辑都完全自定义一切从零开始。前者适合“我想保留现成手势只改激活时机”的场景后者适合“我要实现完全自定义的新手势”的场景。六、配置白名单与使用约束速查6.1 该属性出现在哪些配置入口从源码中搜索manualActivation可确认它被以下位置引用gestureHandlerCommon.tsbaseGestureHandlerWithDetectorProps白名单gesture.tsBaseGestureConfig类型ConfigTypes.tsv3 的CommonGestureConfigpropsWhiteList.tsv3 属性白名单GestureHandler.tsWeb 端激活逻辑实现。6.2 关键约束清单仅连续手势可用manualActivation只出现在“连续手势通用配置”中离散手势如 Tap、Fling 的激活逻辑不使用该属性默认关闭不设置或设为false时手势按各自默认激活条件自动激活必须搭配状态管理器设为true后必须通过GestureStateManager的begin/activate/end/fail驱动状态否则手势将停留在 BEGAN 而无法进入 ACTIVE依赖 react-native-reanimatedGestureStateManager的方法需要在 worklet 中同步执行因此使用手动状态控制前请确认已正确安装并配置react-native-reanimated激活时机限制手势只有在开始接收触摸事件之后才能被激活过早调用activate不会生效。总结manualActivation是 react-native-gesture-handler 连续手势家族中唯一通用的状态控制配置。它以一行布尔属性关闭手势的自动激活能力配合基于handlerTag的GestureStateManager让开发者能够按业务需求精确控制手势的生命周期——无论是“保留原生识别、只改激活时机”manualActivation: true还是“完全自定义识别与状态”Gesture.Manual()。理解其类型签名、底层activate(force)实现与约束边界是编写可靠自定义手势交互的基础。赞分享移动开发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点击查看免费下载相关推荐Cargo Features特性系统全解如何玩转feature统一与resolver v2机制的完整指南Cargo Features特性系统全解如何玩转feature统一与resolver v2机制的完整指南 Cargo 是 Rust 的包管理器The Rus移动开发UI组件react-native-gesture-handler 连续手势公共回调 onUpdate 与 onChange 完全指南react native gesture handler 连续手势公共回调 onUpdate 与 onChange 完全指南 连续手势Continuous G移动开发UI组件7个核心状态详解React Native Gesture Handler手势状态机从BEGAN到END的完整转换指南7个核心状态详解React Native Gesture Handler手势状态机从BEGAN到END的完整转换指南 React Native Gesture移动开发UI组件上一篇Charmbracelet Freeze项目快速入门指南下一篇MLX Swift Examples 项目教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考