Esb*_*ald 7 react-native react-native-scrollview react-native-flatlist
我有一个水平组件<FlatList>,包含 100 个项目(日历天),宽度与屏幕相同。将<FlatList>被设置为捕捉到的间隔类似于屏幕宽度,所以可项之间滑动。
当我滑动到特定日期时,我想更新 UI 以在<FlatList>. 现在我正在使用onMomentumScrollEnd查找最终偏移量和显示在标题中的日期项目。
但是,用户体验不是最佳的,因为在滑动/滚动动画结束之前标题不会更新。
我需要的是一种方法来确定<FlatList>用户一滑动就会捕捉到哪个偏移量。
我想onScroll可能会有用,但是<FlatList>根据我从onScroll.
但是,我可以看到一些 3rd 方模块react-native-snap-carousel正在这样做,使用onScroll,所以我想这是可能的。
我选择不使用,react-native-snap-carousel因为它确实会降低我屏幕上的滑动动画性能。如果模块没有给出明确的答案,请查看代码,因为该模块具有大量我不需要的功能,这些功能是它用于确定下一个snapTo偏移量的代码的一部分
要检测 FlatList 中的“对齐”,您可以使用viewabilityConfig和onViewableItemsChanged Flatlist 属性。
请参阅下面的代码(针对类和Hooks组件),其中我在onViewChanged方法中处理“snap”:
import React, {useRef, useState} from 'react';
import {Dimensions, FlatList, View} from 'react-native';
// CLASS COMPONENT API
export class DemoViewabilityConfigClass extends React.Component {
flatlistRef;
constructor(props) {
super(props);
this.state = {
activeIndex: 0,
};
}
onViewChanged = ({viewableItems, index}) => {
console.log('I snapped to', viewableItems);
if (viewableItems.length > 0) {
const {item: activeItem, index: activeIndex} = viewableItems[0];
console.log(activeItem, activeIndex);
this.setState({activeIndex: activeIndex});
}
};
render() {
return (
<FlatList
ref={ref => (this.flatlistRef = ref)}
showsHorizontalScrollIndicator={false}
contentContainerStyle={{
marginHorizontal: 10,
}}
snapToInterval={Dimensions.get('window').width}
decelerationRate={0}
overScrollMode={'never'}
snapToAlignment={'center'}
data={[
{
id: 'something',
other: 'data',
},
{
id: 'else',
other: 'data',
},
]}
onScrollEndDrag={() => console.log('Scroll end')}
horizontal={true}
viewabilityConfig={{itemVisiblePercentThreshold: 70}}
onViewableItemsChanged={this.onViewChanged}
onScrollToIndexFailed={info => {
console.log('Scroll failed', info);
const wait = new Promise(resolve => setTimeout(resolve, 500));
wait.then(() => {
this.flatlistRef.current?.scrollToIndex({
index: info.index,
animated: true,
});
});
}}
renderItem={({item, index}) => {
return (
<View
style={{
marginRight: 20,
height: 20,
width: Dimensions.get('window').width - 20,
backgroundColor: 'red',
}}
/>
);
}}
/>
);
}
}
// HOOKS API
export function DemoViewabilityConfigHooks() {
const flatlistRef = useRef(null);
const [activeEventIndex, setActiveEventIndex] = useState(0);
const onViewChanged = React.useRef(({viewableItems}) => {
console.log('Items ', viewableItems);
if (viewableItems.length > 0) {
const {index, item} = viewableItems[0];
console.log('Active index', index);
setActiveEventIndex(index);
}
});
const viewConfigRef = React.useRef({viewAreaCoveragePercentThreshold: 50});
return (
<FlatList
ref={flatlistRef}
showsHorizontalScrollIndicator={false}
contentContainerStyle={{
marginHorizontal: 10,
}}
snapToInterval={Dimensions.get('window').width}
decelerationRate={0}
overScrollMode={'never'}
snapToAlignment={'center'}
data={[
{
id: 'something',
other: 'data',
},
{
id: 'else',
other: 'data',
},
]}
onScrollEndDrag={() => console.log('Scroll end')}
horizontal={true}
viewabilityConfig={viewConfigRef.current}
onViewableItemsChanged={onViewChanged.current}
onScrollToIndexFailed={info => {
console.log('Scroll failed', info);
const wait = new Promise(resolve => setTimeout(resolve, 500));
wait.then(() => {
flatlistRef.current?.scrollToIndex({
index: info.index,
animated: true,
});
});
}}
renderItem={({item, index}) => {
return (
<View
style={{
marginRight: 20,
height: 20,
width: Dimensions.get('window').width - 20,
backgroundColor: 'red',
}}
/>
);
}}
/>
);
}
Run Code Online (Sandbox Code Playgroud)
例如,如果您需要更改 onViewChanged 方法内的组件状态,则在使用功能组件/ Hooks API 时需要将这 2 个 props 包装到 Ref() 中。否则,会导致“不支持动态更改 onViewableItemsChanged。 ”错误。此外,您需要使用.current语法将这些 props 传递给 Flalist。
这是 GIF 示例:
| 归档时间: |
|
| 查看次数: |
796 次 |
| 最近记录: |