You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改@gorhom/bottom-sheet代码实现触摸手势上下滑动

解决@gorhom/bottom-sheet触摸手势滑动问题

针对你的需求,要让@gorhom/bottom-sheet支持触摸上下滑动,需检查依赖集成和组件配置,以下是具体修改步骤:

1. 确保react-native-gesture-handler正确集成

在App入口文件(如App.js或index.js)中,用GestureHandlerRootView包裹整个应用,这是手势识别的基础:

import { GestureHandlerRootView } from 'react-native-gesture-handler';

export default function App() {
  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      {/* 你的导航或根组件 */}
    </GestureHandlerRootView>
  );
}

2. 验证react-native-reanimated的Babel配置

在项目根目录的babel.config.js中,确保添加reanimated插件且放在最后一位:

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: ['react-native-reanimated/plugin'],
};

修改后需重启Metro服务,避免缓存导致配置不生效。

3. 修改BottomSheet组件代码

关键调整点:

  • 用BottomSheetScrollView替换内部原生ScrollView,避免手势冲突
  • 通过useMemo定义snapPoints,保证配置稳定性
  • 可选添加enablePanDownToClose,支持向下滑动关闭Sheet

修改后的完整组件代码:

import React, { useState, useCallback, useRef, useMemo } from 'react';
import { View, StyleSheet, Text } from 'react-native';
import { MaterialIcons } from '@expo/vector-icons';
import BottomSheet, { BottomSheetView, BottomSheetScrollView } from "@gorhom/bottom-sheet";

export const Profile = () => {
  const sheetRef = useRef(null);
  
  // 用useMemo缓存snapPoints,避免重复创建
  const snapPoints = useMemo(() => ['25%', '50%', '90%'], []);

  const handleSheetChange = useCallback((index) => {
    console.log('handleSheetChanges', index);
  }, []);

  const handleSnapPress = useCallback((index) => {
    sheetRef.current?.snapToIndex(index);
  }, []);
  
  const handleClosePress = useCallback(() => {
    sheetRef.current?.close();
  }, []);

  // 替换原生ScrollView为BottomSheetScrollView,解决手势冲突
  const renderItem = useCallback(() => (
    <BottomSheetScrollView contentContainerStyle={styles.whiteBoxContent}>
      <View style={styles.infoContainer}>
        <Text style={styles.name}>{card.name},</Text>
        <Text style={styles.age}>{card.age}</Text>
        <View style={styles.ratingContainer}>
          <MaterialIcons name="star-rate" size={36} color="#5285F4" style={styles.starIcon} />
          {roundedRate && <Text style={styles.showRating}>{roundedRate}</Text>}
        </View>
      </View>
    </BottomSheetScrollView>
  ), [card, roundedRate]);

  // 省略其他无关逻辑...

  return (
    <View style={styles.container}>
      <BottomSheet
        ref={sheetRef}
        index={1}
        snapPoints={snapPoints}
        onChange={handleSheetChange}
        enablePanDownToClose={true} // 可选:允许向下滑动关闭Sheet
        enableDynamicSizing={true} // 可选:根据内容动态调整Sheet尺寸
      >
        <BottomSheetView style={styles.contentContainer}>
          {renderItem()}
        </BottomSheetView>
      </BottomSheet>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#f0f0f0',
  },
  contentContainer: {
    flex: 1,
    padding: 16,
  },
  whiteBoxContent: {
    gap: 12,
  },
  infoContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 8,
  },
  name: {
    fontSize: 18,
    fontWeight: 'bold',
  },
  age: {
    fontSize: 16,
  },
  ratingContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    marginLeft: 8,
  },
  starIcon: {
    marginRight: 4,
  },
  showRating: {
    fontSize: 16,
    color: '#5285F4',
  },
});

4. 重启服务测试

修改完成后执行以下步骤:

  • 关闭当前Metro服务
  • 重置缓存并重启Metro:npx react-native start --reset-cache
  • 重新运行项目:npx react-native run-android 或 npx react-native run-ios

常见问题排查

  • 手势仍不生效:检查GestureHandlerRootView是否正确包裹根组件,确认依赖版本兼容(你的版本组合是兼容的)
  • 内部滚动与Sheet手势冲突:确保使用BottomSheetScrollView而非原生ScrollView,它会自动处理手势优先级

内容的提问来源于stack exchange,提问作者Jtigg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 04:55:04