使用 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 工作的代码(没有按钮)

  1. goPrevSlide

    setCurrent(current <= length - 1 && current >= 0 ? current -1 : 0);

    current >= 0 不正确时,因为如果电流等于零,那么在这种情况下您将 -1 设置为电流。替换语句如 setCurrent(current ? current - 1 : length - 1);

  2. 由于更新状态是一个异步操作,你不能立即处理更新的变量,你需要使用 effect 钩子来捕捉它。

    useEffect(() => {
      // fires every time when "current" is updated
      flatListRef.current.scrollToIndex({ index: current, animated: true });
    }, [current]);
    

    从两个处理程序中删除 setCurrent 函数