React Native中BottomSheetModal内FlatList无法滚动问题求助
React Native BottomSheetModal内FlatList无法滚动问题
问题描述
在React Native应用中,将FlatList放入BottomSheetModal实现可选列表项时,FlatList能正常渲染条目,但当条目数量超出屏幕范围时,滚动功能完全失效,无法查看全部内容。
相关代码
BottomSheetModal使用代码
<BottomSheetModalProvider> <Container> <Header title="Home" showDrawerButton /> <View style={{ padding: 20, flex: 1 }}> <CardButton title="Nova venda" onPress={handleSaleModal} /> </View> <KeyboardAvoidingView behavior={Platform.OS === "ios" ? "padding" : "height"} style={{ flex: 1 }} > <BottomSheetModal ref={bottomSheetModalRef} index={1} snapPoints={snapPoints} backgroundStyle={{ borderRadius: 24, backgroundColor: COLORS.GRAY_700, }} handleIndicatorStyle={{ backgroundColor: COLORS.BRAND_LIGHT }} backdropComponent={renderBackdrop} > <ContainerBottomSheet> <Highlight title="Nova venda" subtitle="" /> <View style={{ flex: 1 }}> <CustomSelect data={dataDropdownEmps} onSelect={handleSelect} showSearch /> </View> <Button title="Iniciar" /> </ContainerBottomSheet> </BottomSheetModal> </KeyboardAvoidingView> </Container> </BottomSheetModalProvider>
CustomSelect组件代码
import { CaretDown, CaretUp } from "phosphor-react-native"; import React, { useState } from "react"; import { FlatList, Text, TextInput, TouchableOpacity, View, } from "react-native"; import { useTheme } from "styled-components/native"; import { ButtonSelect, ButtonSelectText, Container } from "./styles"; interface CustomSelectProps { data: SelectItem[]; onSelect: (item: SelectItem | null) => void; showSearch?: boolean; } interface SelectItem { value: string; label: string; } export function CustomSelect({ data, onSelect, showSearch = false, }: CustomSelectProps) { const { COLORS } = useTheme(); const [search, setSearch] = useState(""); const [selectedItem, setSelectedItem] = useState<SelectItem | null>(null); const [isSearchClicked, setIsSearchClicked] = useState(false); const handleSelectItem = (item: SelectItem) => { setSelectedItem(item); onSelect(item); setIsSearchClicked(false); }; const filteredData = data.filter((item) => item.label.toLowerCase().includes(search.toLowerCase()) ); return ( <Container> <ButtonSelect onPress={() => setIsSearchClicked(!isSearchClicked)} activeOpacity={0.7} > <ButtonSelectText> {selectedItem ? selectedItem.label : "Selecione um item"} </ButtonSelectText> {isSearchClicked ? ( <CaretUp size={22} color={COLORS.WHITE} /> ) : ( <CaretDown size={22} color={COLORS.WHITE} /> )} </ButtonSelect> {isSearchClicked && ( <View style={{ width: "100%", borderRadius: 6, marginTop: 10, gap: 10, backgroundColor: "white", elevation: 6, }} > {showSearch && ( <TextInput placeholder="Search..." style={{ width: "90%", height: 54, borderWidth: 0.5, borderColor: "#8e8e8e", borderRadius: 6, alignSelf: "center", marginTop: 10, paddingHorizontal: 10, }} value={search} onChangeText={(text) => setSearch(text)} /> )} <FlatList data={filteredData} renderItem={({ item }) => ( <TouchableOpacity onPress={() => handleSelectItem(item)} style={[ { width: "100%", paddingHorizontal: 10, height: 54, borderBottomWidth: 0.2, borderBottomColor: "#8e8e8e", alignSelf: "center", justifyContent: "center", }, // selectedItem?.value === item.value && styles.selectedItem, ]} > <Text>{item.label}</Text> </TouchableOpacity> )} keyExtractor={(item) => item.value} contentContainerStyle={[{ paddingBottom: 40, maxHeight: 200 }]} /> </View> )} </Container> ); }
已尝试操作
- 检查外层组件是否存在滚动阻塞,未发现异常
- 为FlatList设置
maxHeight属性,问题未解决
排查方向与修复方案
1. 开启嵌套滚动支持(Android)
Android中嵌套滚动容器内的FlatList需要显式开启nestedScrollEnabled属性才能正常响应滚动事件,修改FlatList配置:
<FlatList data={filteredData} renderItem={({ item }) => (...)} keyExtractor={(item) => item.value} contentContainerStyle={[{ paddingBottom: 40 }]} maxHeight={200} nestedScrollEnabled={true} />
2. 正确约束外层容器高度
给包裹FlatList的外层View设置明确的高度限制,确保FlatList有可滚动的空间:
{isSearchClicked && ( <View style={{ width: "100%", borderRadius: 6, marginTop: 10, gap: 10, backgroundColor: "white", elevation: 6, maxHeight: 250, // 留出搜索框空间的高度限制 }} > {/* 搜索框组件 */} <FlatList data={filteredData} renderItem={({ item }) => (...)} keyExtractor={(item) => item.value} contentContainerStyle={[{ paddingBottom: 40 }]} /> </View> )}
3. 使用BottomSheet专属FlatList组件
若使用@gorhom/bottom-sheet库,推荐使用官方提供的BottomSheetFlatList,它会自动处理BottomSheet内部的滚动冲突:
// 导入组件 import { BottomSheetFlatList } from "@gorhom/bottom-sheet"; // 替换原有FlatList <BottomSheetFlatList data={filteredData} renderItem={({ item }) => (...)} keyExtractor={(item) => item.value} contentContainerStyle={[{ paddingBottom: 40 }]} maxHeight={200} />
4. 调整KeyboardAvoidingView布局
外层KeyboardAvoidingView可能干扰BottomSheet的布局计算,尝试将其移至Modal内部或修改behavior属性:
<BottomSheetModal // ...其他属性 > <KeyboardAvoidingView behavior={Platform.OS === "ios" ? "padding" : "padding"} style={{ flex: 1 }} > <ContainerBottomSheet> {/* 原有内容 */} </ContainerBottomSheet> </KeyboardAvoidingView> </BottomSheetModal>
内容的提问来源于stack exchange,提问作者Gustavo Rezin
相关产品推荐
相关产品推荐

