使用 FlatList 在 React Native 中创建 Carousel
create Carousel in React Native using FlatList
我正在使用 FlatList
在 React Native 中创建轮播组件,我使用 useState
挂钩来控制图像的索引,图像加载正确,问题是我无法使用我的按钮来控制旋转木马。例如,当我第一次点击右箭头时不起作用,但当我再次点击时,它会转到下一张图片。
这是我的代码:
const { width: windowWidth, height: windowHeight } = Dimensions.get("window");
const slideList = Array.from({ length: 5 }).map((_, i) => {
return {
id: i.toString(),
image: `https://picsum.photos/1440/2842?random=${i}`,
};
});
const Carousel = () => {
const [current, setCurrent] = useState(0);
const length = slideList.length;
const flatListRef = useRef();
const renderItem = ({ item }) => {
const arr = Object.values( item );
return (
<View style={styles.imagesContainer}>
<Image style={styles.image} source={{ uri: item.image }} />
</View>
);
}
const goNextSlide = () => {
setCurrent(current < length -1 ? current + 1 : 0);
flatListRef.current.scrollToIndex({ index: current, animated: true });
};
const goPrevSlide = () => {
setCurrent(current <= length - 1 && current >= 0 ? current -1 : 0);
flatListRef.current.scrollToIndex({ index: current, animated: true });
};
console.log(current)
return (
<View style={styles.screen}>
<View style={styles.controls}>
<TouchableOpacity style={styles.controlleft} onPress={goPrevSlide}>
<CarouselLeftArrow style={styles.leftArrow} size={28} fill='black' />
</TouchableOpacity>
<TouchableOpacity style={styles.controlRight} onPress={goNextSlide}>
<CarouselRightArrow style={styles.rightArrow} size={28} fill='black' />
</TouchableOpacity>
</View>
<FlatList
data={slideList}
keyExtractor={item => item.id}
renderItem={renderItem}
horizontal={true}
showsHorizontalScrollIndicator={false}
pagingEnabled={true}
ref={flatListRef}
/>
</View>
)
}
const styles = StyleSheet.create({
imagesContainer: {
width: windowWidth,
height: 250
},
image: {
width: '100%',
height: '100%'
},
controls: {
backgroundColor: 'yellow',
flexDirection: 'row',
justifyContent: 'space-between',
position: 'absolute',
zIndex: 2,
width: '100%',
top: 100
},
controlLeft: {
},
controlRight: {
}
})
export default Carousel;
如有任何帮助,我们将不胜感激。
尝试为图像提供宽度和高度,如果源是 uri,则需要。
看到你在 snack 工作的代码(没有按钮)
goPrevSlide
setCurrent(current <= length - 1 && current >= 0 ? current -1 : 0);
当 current >= 0
不正确时,因为如果电流等于零,那么在这种情况下您将 -1 设置为电流。替换语句如 setCurrent(current ? current - 1 : length - 1);
由于更新状态是一个异步操作,你不能立即处理更新的变量,你需要使用 effect
钩子来捕捉它。
useEffect(() => {
// fires every time when "current" is updated
flatListRef.current.scrollToIndex({ index: current, animated: true });
}, [current]);
从两个处理程序中删除 setCurrent
函数
我正在使用 FlatList
在 React Native 中创建轮播组件,我使用 useState
挂钩来控制图像的索引,图像加载正确,问题是我无法使用我的按钮来控制旋转木马。例如,当我第一次点击右箭头时不起作用,但当我再次点击时,它会转到下一张图片。
这是我的代码:
const { width: windowWidth, height: windowHeight } = Dimensions.get("window");
const slideList = Array.from({ length: 5 }).map((_, i) => {
return {
id: i.toString(),
image: `https://picsum.photos/1440/2842?random=${i}`,
};
});
const Carousel = () => {
const [current, setCurrent] = useState(0);
const length = slideList.length;
const flatListRef = useRef();
const renderItem = ({ item }) => {
const arr = Object.values( item );
return (
<View style={styles.imagesContainer}>
<Image style={styles.image} source={{ uri: item.image }} />
</View>
);
}
const goNextSlide = () => {
setCurrent(current < length -1 ? current + 1 : 0);
flatListRef.current.scrollToIndex({ index: current, animated: true });
};
const goPrevSlide = () => {
setCurrent(current <= length - 1 && current >= 0 ? current -1 : 0);
flatListRef.current.scrollToIndex({ index: current, animated: true });
};
console.log(current)
return (
<View style={styles.screen}>
<View style={styles.controls}>
<TouchableOpacity style={styles.controlleft} onPress={goPrevSlide}>
<CarouselLeftArrow style={styles.leftArrow} size={28} fill='black' />
</TouchableOpacity>
<TouchableOpacity style={styles.controlRight} onPress={goNextSlide}>
<CarouselRightArrow style={styles.rightArrow} size={28} fill='black' />
</TouchableOpacity>
</View>
<FlatList
data={slideList}
keyExtractor={item => item.id}
renderItem={renderItem}
horizontal={true}
showsHorizontalScrollIndicator={false}
pagingEnabled={true}
ref={flatListRef}
/>
</View>
)
}
const styles = StyleSheet.create({
imagesContainer: {
width: windowWidth,
height: 250
},
image: {
width: '100%',
height: '100%'
},
controls: {
backgroundColor: 'yellow',
flexDirection: 'row',
justifyContent: 'space-between',
position: 'absolute',
zIndex: 2,
width: '100%',
top: 100
},
controlLeft: {
},
controlRight: {
}
})
export default Carousel;
如有任何帮助,我们将不胜感激。
尝试为图像提供宽度和高度,如果源是 uri,则需要。
看到你在 snack 工作的代码(没有按钮)
goPrevSlide
setCurrent(current <= length - 1 && current >= 0 ? current -1 : 0);
当
current >= 0
不正确时,因为如果电流等于零,那么在这种情况下您将 -1 设置为电流。替换语句如setCurrent(current ? current - 1 : length - 1);
由于更新状态是一个异步操作,你不能立即处理更新的变量,你需要使用
effect
钩子来捕捉它。useEffect(() => { // fires every time when "current" is updated flatListRef.current.scrollToIndex({ index: current, animated: true }); }, [current]);
从两个处理程序中删除
setCurrent
函数