React Native中Gesture Detector无法检测手势问题求助
解决React Native BottomSheet手势检测失效问题
我是React Native新手,跟着教程从零实现BottomSheet组件,但遇到手势检测问题。以下代码中的Pan手势无法被检测到,终端无任何输出:
const gesture= Gesture.Pan().onUpdate((event)=>{ console.log(event.translationX); });
相关代码及配置
CongeScreen.js
import React from 'react'; import Header from '../../components/Header'; import { GestureHandlerRootView } from 'react-native-gesture-handler'; import { Host, Portal } from 'react-native-portalize'; import { SafeAreaView, StyleSheet, Text, useColorScheme, View, Image, TextInput, TouchableOpacity } from 'react-native'; import { Colors, DebugInstructions, LearnMoreLinks, ReloadInstructions, } from 'react-native/Libraries/NewAppScreen'; import BottomSheet from '../../components/BottomSheet' import { Modal } from 'react-native-paper'; const CongeScreen: () => Node = ({navigation}) => { return ( <SafeAreaView style={styles.body}> <GestureHandlerRootView style={{ flex: 1 }}> <View style={styles.container}> <Header titre={'Mes congés'} /> <View style={styles.viewEmpty}> <Text style={styles.textEmpty}>Vous n'avez pas encore de congés</Text> <Image style={{marginTop:35}} source={require('../../assets/calendar-xmark-solid.png')} /> </View> <View styles={styles.line} /> </View> <BottomSheet /> </GestureHandlerRootView> </SafeAreaView> ); }; const styles = StyleSheet.create({ body:{ flex:1, backgroundColor:'#202020', fontFamily:'Montserrat-Regular', color:'#E9E9E9', }, container:{ paddingVertical:60, paddingHorizontal:20, }, viewEmpty:{ alignItems:'center' }, textEmpty:{ color:'#484848', fontFamily:'Montserrat-Bold', fontSize:16 } }); export default CongeScreen;
BottomSheet.js
import React from 'react'; import { Dimensions,StyleSheet, Text, View } from "react-native"; import { Gesture, GestureDetector } from 'react-native-gesture-handler'; const { height:SCREEN_HEIGHT }= Dimensions.get('window'); import { Host, Portal } from 'react-native-portalize'; import Animated from 'react-native-reanimated'; const BottomSheet =() =>{ const gesture= Gesture.Pan().onUpdate((event)=>{ console.log(event.translationX); }) return ( <Portal> <GestureDetector gesture={gesture}> <Animated.View style={styles.bottomSheetContainer}> <View style={styles.line} /> </Animated.View> </GestureDetector> </Portal> ) } const styles=StyleSheet.create({ bottomSheetContainer:{ height: SCREEN_HEIGHT, width:'100%', backgroundColor:'white', position:'absolute', top:SCREEN_HEIGHT/1.5, borderRadius:25, }, line:{ height:3, width:50, backgroundColor:'grey', alignSelf:'center', marginVertical:10, borderRadius:2 } }); export default BottomSheet;
依赖项
"dependencies": { "@gorhom/portal": "^1.0.14", "@react-navigation/bottom-tabs": "^6.3.2", "@react-navigation/native": "^6.0.11", "@react-navigation/native-stack": "^6.7.0", "@react-navigation/stack": "^6.2.2", "react": "18.0.0", "react-native": "0.69.3", "react-native-gesture-handler": "^2.5.0", "react-native-linear-gradient": "^2.6.2", "react-native-paper": "^4.12.4", "react-native-portalize": "^1.0.7", "react-native-reanimated": "^2.9.1", "react-native-safe-area-context": "^4.3.1", "react-native-screens": "^3.15.0", "react-native-svg": "^12.4.3", "react-native-vector-icons": "^9.2.0" }
babel.config.js
module.exports = { presets: ['module:metro-react-native-babel-preset'], plugins: [ 'react-native-reanimated/plugin', ], };
问题排查与解决方案
1. 修正GestureHandlerRootView层级
BottomSheet通过Portal渲染,会挂载到应用根节点,而非当前页面的GestureHandlerRootView上下文。需将整个应用根组件包裹在GestureHandlerRootView内,而非仅在CongeScreen中:
// App.js 应用入口文件 import { GestureHandlerRootView } from 'react-native-gesture-handler'; import { NavigationContainer } from '@react-navigation/native'; import { Host } from 'react-native-portalize'; export default function App() { return ( <GestureHandlerRootView style={{ flex: 1 }}> <Host> <NavigationContainer> {/* 你的导航栈或页面组件 */} </NavigationContainer> </Host> </GestureHandlerRootView> ); }
2. 调整手势监听方向与逻辑
BottomSheet为垂直拖动场景,需显式指定手势方向,并监听Y轴位移(而非X轴):
const gesture = Gesture.Pan() .direction(Gesture.DIRECTION_VERTICAL) .onUpdate((event) => { console.log(event.translationY); // 输出垂直方向位移 });
3. 完善Portal配套组件
react-native-portalize的Portal必须配合根节点的Host组件使用,否则无法正确渲染到上下文,已在步骤1的App.js中添加。
4. 清除缓存重新构建
修改babel配置后,需清除缓存并重新编译项目:
npx react-native start --reset-cache npx react-native run-android # 或 run-ios
内容的提问来源于stack exchange,提问作者mohamed yassine khabthani
相关产品推荐
相关产品推荐

