I'm trying to implement carousel using React Native Animated.FlatList
, which should scroll automatically. But the problem is that, I cannot control the animation speed of scroll. When .scrollToIndex
is called, FlatList items always move with one and the same speed.
Here's my code:
export const Carousel = ({ data }: CarouselProps) => {
const width = Dimensions.get('window').width - 20;
const flatListRef = useRef<FlatList>(null);
const scrollX = useRef(new Animated.Value(0)).current;
const [currentIndex, setCurrentIndex] = useState<number>(0);
useEffect(() => {
const interval = setInterval(() => {
if (currentIndex === data.length - 1) {
flatListRef.current?.scrollToIndex({
index: 0,
animated: true,
});
setCurrentIndex(0);
} else {
const nextIndex = Math.floor(currentIndex) + 1;
flatListRef.current?.scrollToIndex({
index: nextIndex,
animated: true,
});
setCurrentIndex(nextIndex);
}
}, 3000);
return () => clearInterval(interval);
}, [currentIndex, data.length]);
const renderItem = useCallback(
({ title }: { title: string }, index: number) => {
return (
<MotiView
key={index}
style={{ width, borderColor: 'red', borderWidth: 2 }}
transition={{
duration: 2000,
type: 'timing',
}}
>
<Text>{title}</Text>
</MotiView>
);
},
[currentIndex, width]
);
const handleScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {
Animated.event([{
nativeEvent: {
contentOffset: {
x: scrollX,
},
},
}], { useNativeDriver: true }
);
};
const getItemLayout = (data: any, index: number) => ({
length: width,
offset: width * index,
index,
});
return (
<View style={{ height: 100 }}>
<Text>Welcome to Carousel!</Text>
<Animated.FlatList
ref={flatListRef}
data={data}
keyExtractor={(item) => item.id}
renderItem={({ item, index }) => renderItem(item, index)}
horizontal={true}
onScroll={handleScroll}
pagingEnabled={true}
showsHorizontalScrollIndicator={false}
getItemLayout={getItemLayout}
/>
</View>
);
};
export default Carousel;