关于rngh手势与Slider组件手势与事件冲突解决问题记录

在rngh(react-native-gesture-handler) 是rn一个常用的原生手势库,其手势响应运行在原生层,相比rn原生的具备更高性能与更快响应,本文主要记录其与手势与事件冲突问题 个人使用的是rngh v2版本

本文解决的是嵌套在GestureDetector内部想要触发事件的问题。

1.普通按钮与手势冲突

js 复制代码
function(){
return 

<>
     <GestureDetector>   
     //其他组件
   //按钮部分   <Button/>..
       //其他组件
     </GestureDetector>
</>
}

以上代码结构是常规的按钮被GestureDetector包裹,在这块只会触发rngh的手势,无法触发按钮事件

使用Pressable组件

该组件是rngh导出的组件,使用的是原生层级的响应,可以与GestureDetector包裹配置的手势同时触发,需要设置变量去拦截手势触发的逻辑,不推荐

嵌套GestureDetector

js 复制代码
  const playButtonGesture = Gesture.Tap().runOnJS(true);
        
  const onceTap = Gesture.Tap()
    .requireExternalGestureToFail(playButtonGesture)
    .maxDuration(350)

    .onStart(() => {
      console.log("点击");


    });
     <GestureDetector  gesture={Gesture.Race(onceTap)}>   
         <View>
           //其他组件
              <GestureDetector gesture={playButtonGesture}>   
                 <View>
                //按钮部分
                </View>
             </GestureDetector>
           //其他组件
         </View>
     </GestureDetector>
</>

通过嵌套GestureDetector给内部设置单独的手势并且使用requireExternalGestureToFail在外层排除内部手势,这样就做到了对内部按钮单独的点击响应

2.组件事件与原生冲突

就以@react-native-community/slider为例

js 复制代码
import Slider from "@react-native-community/slider";
import { useState } from "react";
import { View } from "react-native";
import { Gesture, GestureDetector } from "react-native-gesture-handler";

function Test() {
  const [currentTime, setCurrentTime] = useState(0);
  // 为Slider创建专用手势
  const sliderGesture = Gesture.Native();
  return (
    <>
    //1.包裹在内部
      <GestureDetector gesture={sliderGesture}>
        <View>
          <Slider
            minimumTrackTintColor={"rgba(102, 51, 255, 1)"}
            maximumTrackTintColor={"rgba(230, 230, 230, 1)"}
            thumbTintColor={"rgba(102, 51, 255, 1)"}
            minimumValue={0}
            maximumValue={200}
            value={currentTime}
            onTouchStart={() => {
              console.log("onTouchStart");
            }}
            onSlidingStart={(value) => {
              console.log(value, "onSlidingStart");
            }}
            onValueChange={(val) => {
              setCurrentTime(val);
              console.log("onValueChange");
            }}
            onSlidingComplete={() => {
              console.log("onSlidingComplete");
            }}
          />
        </View>
      </GestureDetector>
         //2.不包裹在内部没有问题
      <Slider
        minimumTrackTintColor={"rgba(102, 51, 255, 1)"}
        maximumTrackTintColor={"rgba(230, 230, 230, 1)"}
        thumbTintColor={"rgba(102, 51, 255, 1)"}
        minimumValue={0}
        maximumValue={200}
        value={currentTime}
        onTouchStart={() => {
          console.log("onTouchStart");
        }}
        onSlidingStart={(value) => {
          console.log(value, "onSlidingStart");
        }}
        onValueChange={(val) => {
          setCurrentTime(val);
          console.log("onValueChange");
        }}
        onSlidingComplete={() => {
          console.log("onSlidingComplete");
        }}
      />
    </>
  );
}

export default Test;

包裹在内部需要使用Gesture.Native();这样手势拦截后会把事件转移到Slider组件,这样就可以触发onSlidingComplete。

目前存在的问题就是Slider组件无法拖动,个人在寻找解决方案中,也寻找答案

当然,最能解决的方案就是不嵌套在GestureDetector内部!

相关推荐
美狐美颜sdk2 小时前
直播APP开发技术栈详解:视频美颜SDK、人脸识别与实时渲染
android·人工智能·音视频·美颜sdk·直播美颜sdk
默_笙6 小时前
🚋 从流水线到地铁网:为什么复杂 AI 都要拆成多 Agent(上)——LangGraph 基础入门
前端·javascript
ID34610744207 小时前
【课程设计】基于Spring Boot+Vue的游戏账号租赁系统的设计与实现-计算机毕设 附源码50345
javascript·vue.js·spring boot·python·node.js·php·课程设计
柚yuzumi7 小时前
彻底搞懂 JavaScript 类型转换:显式转换、隐式转换与 ToPrimitive
前端·javascript·node.js
奈斯先生Vector7 小时前
当模型版本不断变化,RelayRouter 能否帮助 AI 应用摆脱深度绑定
android·java·人工智能·开源·aigc
TimeFine7 小时前
让强模型做“总工”,让高性价比模型写代码
android
AI情绪识别开源8 小时前
检信ALLEMOTION 认知评估分析器 · WebSocket 推送数据文档
javascript
OpsEye8 小时前
公司内部全员使用 AI,如何保证会话合规、行为可审计?
javascript·ai编程
又见情义9 小时前
RK3568 Android 13 屏蔽 healthd 电池日志经验分享
android