关于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内部!

相关推荐
用户2018792831672 小时前
浅析Binder通信的三种调用方式
android
艾小码2 小时前
用了这么久React,你真的搞懂useEffect了吗?
前端·javascript·react.js
干就完了12 小时前
js对象常用方法都在这,使用时想不到?不存在的
前端·javascript
艾小码2 小时前
还在硬邦邦跳转页面?Vue这3招让应用丝滑如德芙!
前端·javascript·vue.js
子兮曰2 小时前
🚀前端依赖配置避坑指南:深度解析package.json中devDependencies的常见误解
前端·javascript·npm
forever_Mamba2 小时前
实现一个高性能倒计时:从踩坑到最佳实践
前端·javascript
小帆聊前端2 小时前
JS 原型链深度解读:从混乱到通透,掌握 90% 前端面试核心
javascript
子兮曰2 小时前
浏览器与 Node.js 全局变量体系详解:从 window 到 global 的核心差异
前端·javascript·node.js
召摇2 小时前
API 设计最佳实践 Javascript 篇
前端·javascript·vue.js