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

@gorhom/bottom-sheet的BottomSheetScrollView无法滚动问题求助

@gorhom/bottom-sheet的BottomSheetScrollView无法滚动问题求助

大家好,我最近在使用@gorhom/bottom-sheet组件时卡壳了,遇到一个特别头疼的问题:当TextInput获焦弹出的弹窗里,用BottomSheetScrollView渲染的搜索结果列表完全无法滚动,试了各种布局调整都没效果,我怀疑是嵌套组件的布局约束出了问题,想请各位大佬帮忙看看!

先说说场景:弹窗是基于自己封装的DefaultPopup组件实现的,里面嵌套了BottomSheetView和BottomSheetScrollView,我塞了一堆测试用的CountrySearchResult组件模拟长列表,但不管怎么滑动都没反应,连onScroll的日志都打不出来,实在摸不着头脑。

我的弹窗代码:

<DefaultPopup 
  title="" // 无标题
  isVisible={isCountrySearchPopupVisible} 
  minPoint={false} // 不设置最小停靠点
  extraComp={ 
    <BottomSheetView 
      style={{ 
        // backgroundColor: "red", 
        // flex: 1, 
        marginTop: Dimensions.get("screen").height * 0.069 + SPACING * 3, 
        // height: 100, 
        paddingHorizontal: SPACING * 3, 
      }} 
    > 
      <Line /> 
      <BottomSheetScrollView 
        contentContainerStyle={{ backgroundColor: "red" }} 
        // onScroll={() => console.log("hi")} 
      > 
        <CountrySearchResult isoCode="Be" /> 
        <CountrySearchResult isoCode="Be" /> 
        <CountrySearchResult isoCode="Be" /> 
        <CountrySearchResult isoCode="Be" /> 
        <CountrySearchResult isoCode="Be" /> 
        <CountrySearchResult isoCode="Be" /> 
        <CountrySearchResult isoCode="Be" /> 
        <CountrySearchResult isoCode="Be" /> 
        <CountrySearchResult isoCode="Be" /> 
        <CountrySearchResult isoCode="Be" /> 
        <CountrySearchResult isoCode="Be" /> 
        <CountrySearchResult isoCode="Be" /> 
        <CountrySearchResult isoCode="Be" /> 
        <CountrySearchResult isoCode="Be" /> 
        <CountrySearchResult isoCode="Be" /> 
        <CountrySearchResult isoCode="Be" /> 
        <CountrySearchResult isoCode="Be" /> 
        <CountrySearchResult isoCode="Be" /> 
        <CountrySearchResult isoCode="Be" /> 
      </BottomSheetScrollView> 
    </BottomSheetView> 
  } 
  setIsVisible={() => setIsCountrySearchPopupVisible((prev) => !prev)} 
/>

封装的DefaultPopup组件代码:

import { Dimensions, StyleSheet, Text, View } from "react-native";
import { useEffect, useRef, useState } from "react";
// 常量
import { SECONDARY_COLOR, BACKGROUND_COLOR, SPACING, BLUR } from "@env";
// Expo组件
import { BlurView } from "expo-blur";
// 通用组件
import DefaultText from "../../components/general/DefaultText";
// 第三方包
import BottomSheet, { BottomSheetView, BottomSheetModalProvider } from "@gorhom/bottom-sheet";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import Animated, { useSharedValue, withTiming, runOnJS } from "react-native-reanimated";

// 注意:只能在Tabs外部使用,否则动画和BottomSheet会出问题!
const DefaultPopup = ({ 
  maxPoint = "80%", 
  minPoint = "20%", 
  extraComp = "", 
  title = "", 
  description = "", 
  isVisible = true, // 弹窗显示状态
  setIsVisible = () => {}, // 弹窗切换函数
  noClose, 
}) => { 
  // BottomSheet引用,用于控制开合
  const bottomSheetRef = useRef(null); 
  // 控制遮罩层显隐,避免遮罩影响下层Tabs点击
  const [displayForAnimatedView, setDisplayForAnimatedView] = useState(isVisible); 
  // 遮罩层透明度动画值
  const opacity = useSharedValue(0); 

  // 弹窗停靠点配置:如果minPoint为false则只有一个停靠点
  const snapPoints = !minPoint ? [maxPoint] : [minPoint, maxPoint]; 

  // 弹窗显隐时触发遮罩动画
  useEffect(() => { 
    opacity.value = withTiming( 
      isVisible ? 1 : 0, 
      { duration: 100 }, 
      (isFinished) => { 
        // 动画结束后更新遮罩显隐状态
        if (isFinished) { 
          runOnJS(setDisplayForAnimatedView)(isVisible); 
          // 弹窗显示时自动展开到最大停靠点
          isVisible && runOnJS(bottomSheetRef.current.snapToIndex)( 
            snapPoints.length - 1 
          ); 
        } 
      } 
    ); 
  }, [isVisible]); 

  return ( 
    <> 
      {/* 模糊遮罩层 */} 
      <Animated.View 
        style={[ 
          styles.animationView, 
          { opacity, display: displayForAnimatedView ? "flex" : "none" }, 
        ]} 
      > 
        <BlurView intensity={BLUR} style={styles.blurView}></BlurView> 
      </Animated.View> 

      {/* 手势处理容器,必须包裹BottomSheet */} 
      <View 
        style={[ 
          styles.gestureHandlerView, 
          { display: isVisible ? "flex" : "none" }, 
        ]} 
      > 
        <BottomSheet 
          ref={bottomSheetRef}
          snapPoints={snapPoints}
          enableDynamicSizing={false} 
          enablePanDownToClose={!noClose} // 是否允许下拉关闭
        >
          {extraComp}
        </BottomSheet>
      </View> 
    </> 
  ); 
};

const styles = StyleSheet.create({
  animationView: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    zIndex: 100,
  },
  blurView: {
    flex: 1,
    backgroundColor: BACKGROUND_COLOR,
  },
  gestureHandlerView: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    zIndex: 101,
  },
});

export default DefaultPopup;

我试过的调试操作:

  1. 给BottomSheetScrollView加了红色背景,能看到它确实占据了列表空间,但滑动完全没反应
  2. 开启onScroll日志监听,一次都没触发过
  3. 调整BottomSheetView的flex、height属性,要么列表被截断要么还是无法滚动

我猜可能是BottomSheet的父容器没有正确设置高度约束,或者BottomSheetScrollView的滚动手势被上层组件拦截了?有没有用过这个组件的朋友遇到过类似问题,求给点思路!

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 13:33:02