React Native Expo中设置FlatList滚动宽度实现周选择器
问题描述
尝试用FlatList实现日期选择器,渲染多个可横向滚动的周(如week1、week2等),期望单个周占满设备宽度,滚动时自动对齐到单个周,始终完整显示周日至周六,但当前一屏约显示1.75个周,尝试过justifyContent和flexGrow属性效果不佳,需要实现每次仅滚动一个周的效果。
现有代码
组件代码
const Week = ({ item, selectedId, setSelectedId }) => ( <View style={styles.weekContainer}> {item.days.map((day) => { return ( <TouchableOpacity onPress={() => setSelectedId(day.id)} style={[ day.id == selectedId ? styles.unselectedDay : styles.selectedDay, ]} key={day.id} > <Text style={[ day.id == selectedId ? styles.unselectedDayText : styles.selectedDayText ]} > {day.name} </Text> </TouchableOpacity> ) })} </View> ); export const DateHeader = () => { const [selectedId, setSelectedId] = useState(today.toLocaleDateString()); const width = Dimensions.get('window').width const renderItem = ({ item }) => { return ( <Week item={item} selectedId={selectedId} setSelectedId={setSelectedId} /> ); } return (<> <FlatList data={weeks} renderItem={renderItem} keyExtractor={(item) => item.id} extraData={selectedId} horizontal={true} inverted={true} style={styles.flatList} showsHorizontalScrollIndicator={false} decelerationRate={0} snapToInterval={width} snapToAlignment={'center'} /> </>) }
样式代码
const styles = StyleSheet.create({ flatList: { flexGrow: 0, }, weekContainer: { flexGrow: 1, flexDirection: 'row', borderColor:'red', borderWidth: '2px', }, unselectedDay: { fontSize: 16, padding: 10, height: 50, backgroundColor: '#6e3b6e', }, selectedDay: { fontSize: 16, padding: 10, height: 50, backgroundColor: '#f9c2ff', }, unselectedDayText: { textColor: 'white' }, selectedDayText: { textColor: 'black' }, });
当前效果

解决方案
问题核心在于每个Week组件的容器未设置固定宽度,导致FlatList无法正确计算项宽,进而影响滚动对齐效果,按以下步骤修改即可:
给周容器设置固定屏幕宽度
在DateHeader中已获取width = Dimensions.get('window').width,直接传递给Week组件并设置宽度:// 修改Week组件接收width参数并设置容器宽度 const Week = ({ item, selectedId, setSelectedId, width }) => ( <View style={[styles.weekContainer, { width: width }]}> {/* 原有内容不变 */} </View> ); // 在renderItem中传递width const renderItem = ({ item }) => { return ( <Week item={item} selectedId={selectedId} setSelectedId={setSelectedId} width={width} /> ); }同时移除
weekContainer的flexGrow:1,固定宽度下无需该属性:weekContainer: { // flexGrow: 1, // 移除此行 flexDirection: 'row', borderColor:'red', borderWidth: 2, // React Native中borderWidth无需加px,直接写数字 },优化FlatList滚动对齐参数
将snapToAlignment改为'start',让滚动后周从屏幕左侧对齐,同时添加disableIntervalMomentum让滚动更干脆:<FlatList // 其他属性不变 snapToInterval={width} snapToAlignment={'start'} disableIntervalMomentum={true} />修复样式错误
React Native的Text样式中没有textColor属性,替换为color:unselectedDayText: { color: 'white' }, selectedDayText: { color: 'black' },
修改完成后,每个周容器会占满屏幕宽度,滚动时自动对齐单个周,每次滚动仅切换一个周的内容。
内容的提问来源于stack exchange,提问作者benwl
相关产品推荐
相关产品推荐

