0

我对 React Native 有点陌生,我正在尝试使用 Flatlist 创建一个卡片列表,我想为每张卡片显示几个图像作为轮播,我正在尝试使用 react-native-snap-carousel ,问题是当我滚动一张卡片时,所有卡片的索引都会移动。

如何为每张卡获取单独的索引?

import React, { useState, useRef } from 'react';
import { View, Text, Dimensions } from 'react-native';
import Carousel, { Pagination } from 'react-native-snap-carousel';

const { width: screenWidth, height: screenHeight } = Dimensions.get('window');

const myCarousel = () => {
  const [activeSlide, setActiveSlide] = useState(0);
  const carousel = useRef();
  const entries = [
    {
      title: 'card1',
    },
    {
      title: 'card2',
    },
    {
      title: 'card3',
    },
    {
      title: 'card4',
    },
  ];

  var slides = [];

  const entriesSplitter = () => {
    let size = 1; //Based on the size you want
    while (entries.length > 0) {
      slides.push(entries.splice(0, size));
    }
  };

  // render every single slide
  const _renderItem = ({ item, index }) => {
    return (
      <View style={{ flexDirection: 'row', flexWrap: 'wrap' }}>
        {item.map(item => {
          return <Text key={index}>{item.title}</Text>;
        })}
      </View>
    );
  };

  return (
    <View>
      {entriesSplitter()}
      <Carousel
        ref={carousel}
        data={slides}
        renderItem={_renderItem}
        onSnapToItem={index => setActiveSlide(index)}
        sliderWidth={screenWidth}
        sliderHeight={screenHeight}
        itemWidth={screenWidth}
      />
      <Pagination
        dotsLength={4} // also based on number of sildes you want
        activeDotIndex={activeSlide}
        containerStyle={{ backgroundColor: 'red', borderWidth: 2 }}
        dotStyle={{
          width: 10,
          height: 10,
          borderRadius: 5,
          marginHorizontal: 8,
          backgroundColor: 'black',
        }}
        inactiveDotStyle={{
          backgroundColor: 'pink',
        }}
        inactiveDotOpacity={0.4}
        inactiveDotScale={0.6}
      />
      <Carousel
        ref={carousel}
        data={slides}
        renderItem={_renderItem}
        onSnapToItem={index => setActiveSlide(index)}
        sliderWidth={screenWidth}
        sliderHeight={screenHeight}
        itemWidth={screenWidth}
      />
      <Pagination
        dotsLength={4} // also based on number of sildes you want
        activeDotIndex={activeSlide}
        containerStyle={{ backgroundColor: 'red', borderWidth: 2 }}
        dotStyle={{
          width: 10,
          height: 10,
          borderRadius: 5,
          marginHorizontal: 8,
          backgroundColor: 'black',
        }}
        inactiveDotStyle={{
          backgroundColor: 'pink',
        }}
        inactiveDotOpacity={0.4}
        inactiveDotScale={0.6}
      />
    </View>
  );
};

export default myCarousel;

索引有一种圆圈样式,当你转到下一个时,会改变颜色以指示还剩多少,它们都同时移动

4

3 回答 3

0

最后我设法做我想做的事,虽然索引移动太慢,但我分享我的代码以防它可以帮助某人。

状态:

constructor(props) {
  super(props);

  this.state = {
    activeSlide: [],
  };
}

使成为:

  render() {
    const {cards} = this.props;
    return (
      <View>
        <FlatList
          data={cards}
          numColumns={2}
          renderItem={({item, index}) => this._renderItemCarousel(item, index)}
        />
      </View>
    );
  }

_renderItemCarousel:

  _renderItemCarousel = (card, index) => (
    <View style={styles.card}>
      <Carousel
        data={card.picks}
        renderItem={this._renderItem}
        onSnapToItem={indexC => this.setIndex(indexC, {index})}
        sliderWidth={screenWidth}
        sliderHeight={screenHeight}
        itemWidth={screenWidth}
      />

      <Pagination
        dotsLength={card.picks.length}
        activeDotIndex={this.getIndex({index})}
        containerStyle={styles.circleDiv}
        dotStyle={styles.whiteCircle}
        inactiveDotOpacity={0.4}
        inactiveDotScale={0.6}
      />
    </View>
  );

设置索引,获取索引:

    setIndex = (indexC, indexF) => {
    let activeSlide = [...this.state.activeSlide];
    activeSlide[indexF.index] = indexC;
    this.setState({activeSlide});
  };
  getIndex = index => {
    if (this.state.activeSlide[index.index] == undefined) {
      this.state.activeSlide.push(0);
    }
    return this.state.activeSlide[index.index];
  };

_renderItem:

  _renderItem = ({item, index}) => {
    return (
      <View>
        <Image
          key={item.url}
          source={item.image}
          style={{height: '100%', width: CARD_WIDTH}}
        />
      </View>
    );
  };
于 2020-04-02T12:15:37.317 回答
0

您正在使用两个具有相同参考和相同变量的 cousel,因此您需要将它们分开

Working example: https://snack.expo.io/@msbot01/joyous-carrot
import React, {useState, useRef} from 'react';
import { Text, View, StyleSheet, Dimensions, Image } from 'react-native';
import Constants from 'expo-constants';

// You can import from local files
import AssetExample from './components/AssetExample';
import Carousel, {Pagination} from 'react-native-snap-carousel';

const screenWidth = Math.round(Dimensions.get('window').width);
const screenHeight = Math.round(Dimensions.get('window').height);

// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';

export default function App() {
  const [activeSlide, setActiveSlide] = useState(0);
  const [activeSlide2, setActiveSlide2] = useState(0);

  const entries = [
    { 
      title: 'card1',
    },
    {
      title: 'card2',
    },
    { 
      title: 'card3',
    },
    {
      title: 'card4',
    },
  ];
  const entries2 = [
    {
      title: 'card1',
    },
    {
      title: 'card2',
    },
    { 
      title: 'card3',
    },
    {
      title: 'card4',
    },
  ];

  var slides = [];

  const entriesSplitter = () => {
    let size = 1; //Based on the size you want
    while (entries.length > 0) {
      slides.push(entries.splice(0, size));
    }
  };

  // render every single slide
  const _renderItem = ({item, index}) => {
    return (
          <View style={{backgroundColor:'green', justifyContent:'center', alignItems:'center'}}>
            <Image
                style={{height:screenHeight/2, width:screenWidth-100}}
                source={{
                  uri: 'https://reactnative.dev/img/tiny_logo.png',
                }}
              />
        </View>

    );
  }

  const _renderItem2 = ({item, index}) => {
    return (
          <View style={{backgroundColor:'yellow', justifyContent:'center', alignItems:'center'}}>
            <Image
                style={{height:screenHeight/2, width:screenWidth-100}}
                source={{
                  uri: 'https://reactnative.dev/img/tiny_logo.png',
                }}
              />
        </View>

    );
  }

  return (
    <View style={styles.container}>
      <Carousel
        ref={(c) => { this._carousel = c}}
        data={entries}
        renderItem={_renderItem}
        onSnapToItem={index => setActiveSlide(index)}
        sliderWidth={screenWidth-20}
        sliderHeight={(screenHeight-100)}
        itemWidth={screenWidth-50}
      />
      {<Pagination
        dotsLength={4} // also based on number of sildes you want
        activeDotIndex={activeSlide}
        containerStyle={{backgroundColor: 'red', borderWidth: 2}}
        dotStyle={{
          width: 10,
          height: 10,
          borderRadius: 5,
          marginHorizontal: 8,
          backgroundColor: 'black',
        }}
        inactiveDotStyle={{
          backgroundColor: 'pink',
        }}
        inactiveDotOpacity={0.4}
        inactiveDotScale={0.6}
      />}
      <Carousel
        ref={(c) => { this._carousel2 = c}}
        data={entries2}
        renderItem={_renderItem2}
        onSnapToItem={index => setActiveSlide2(index)}
        sliderWidth={screenWidth-20}
        sliderHeight={(screenHeight-100)}
        itemWidth={screenWidth-50}
      />

      {<Pagination
        dotsLength={4} // also based on number of sildes you want
        activeDotIndex={activeSlide2}
        containerStyle={{backgroundColor: 'red', borderWidth: 2}}
        dotStyle={{ 
          width: 10,
          height: 10,
          borderRadius: 5,
          marginHorizontal: 8,
          backgroundColor: 'black',
        }}
        inactiveDotStyle={{
          backgroundColor: 'pink',
        }}
        inactiveDotOpacity={0.4}
        inactiveDotScale={0.6}
      />}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 8,
  }
});
于 2020-03-31T13:43:58.390 回答
0

要创建动态轮播,您可以使用地图来遍历数组:

 Array.map((i) =>{
          return <item><img src={i} alt="image"></img></item>
        })
于 2021-04-01T09:39:37.347 回答