我有一个具有水平<FlatList>的组件,该组件包含100多个项目(日历日),其宽度与屏幕相同。<FlatList>设置为与屏幕宽度类似的间隔,因此我可以在项之间滑动。
当我滑动到特定日期时,我想更新UI以显示该日期,在<FlatList>之上。现在,我正在使用onMomentumScrollEnd查找最终偏移量和标题中显示的日期项。
但是,用户体验并不是最优的,因为在滑动/滚动动画结束之前没有更新标头。
我需要的是一种方法,以确定哪个偏移,<FlatList>将快照,一旦用户滑动。
我想onScroll可能是有用的,但是根据我从onScroll得到的事件,我有点迷失在寻找下一个偏移量帽子的<FlatList>上。
但是,我可以看到像react-native-snap-carousel这样的第三方模块正在使用onScroll,所以我想这是可能的。
我选择不使用react-native-snap-carousel,因为它确实降低了屏幕上的滑动动画性能。如果模块没有给出明确的答案,查看代码,因为这个模块有很多我不需要的特性,这些特性是它用来确定下一个snapTo offSet的代码的一部分。
发布于 2021-10-03 17:03:43
要检测viewabilityConfig中的"snap“,可以使用FlatList和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',
}}
/>
);
}}
/>
);
}例如,如果需要在onViewChanged方法中更改组件状态,则在使用Functional / Hooks时,需要将这2个支持包到Ref()中。否则,会导致“不支持动态更改onViewableItemsChanged”。错误。此外,您还需要使用.current语法将这些道具传递给Flalist。
下面是GIF示例:

https://stackoverflow.com/questions/57633835
复制相似问题