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

相关推荐
用户20187928316718 分钟前
浅谈Android PID与UID原理
android
TimeFine24 分钟前
Android AWS KVS WebRTC 通话声道切换到媒体音乐声道
android
星秀日1 小时前
JavaWeb--Ajax
前端·javascript·ajax
用户2018792831672 小时前
Android文件下载完整性保证:快递员小明的故事
android
用户2018792831672 小时前
自定义 View 的 “快递失踪案”:为啥 invalidate () 喊不动 onDraw ()?
android
没有了遇见2 小时前
Android 稀奇古怪系列:新版本签名问题-Algorithm HmacPBESHA256 not available
android
嫂子的姐夫2 小时前
10-七麦js扣代码
前端·javascript·爬虫·python·node.js·网络爬虫
Komorebi_99992 小时前
Vue3 + TypeScript provide/inject 小白学习笔记
前端·javascript·vue.js
少吃一口都不行2 小时前
脚手架学习
前端·javascript·学习
小妖怪的夏天2 小时前
react native android设置邮箱,进行邮件发送
android·spring boot·react native