react-native-swiper: Images not loading on Android

The library works perfectly on iOS, but a Swiper of Images on the Android version won’t display its images. The code:

<Swiper showsButtons={false} style={{}} loop={true} height={screenWidth} width={screenWidth}
      dot={<View style={{backgroundColor: 'rgba(255,255,255,.7)', width: 5, height: 5, borderRadius: 4, marginLeft: 3, marginRight: 3, marginTop: 3, marginBottom: 3}} />}
      activeDot={<View style={{backgroundColor: '#49D2FF', width: 8, height: 8, borderRadius: 4, marginLeft: 3, marginRight: 3, marginTop: 3, marginBottom: 3}} />}
      paginationStyle={{bottom: 10,}} >
           {finalPhotos.map((item, key) => {
              return (
               <Image key={key} style={{flex:1,width:screenWidth,height:screenWidth,}} source={key === 0 ? (item == "none" ? require("./img/missing-pic-icon.png") : {uri:item}) : {uri:item.image}} />
              );
      })}
</Swiper>

Other details to note: -Once again, there are no issues on iOS -The swiper is contained in a View that’s contained in another Swiper -The finalPhotos array is made before returning the overall render function

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Reactions: 17
  • Comments: 15

Most upvoted comments

same in flatlist on Android. but not in flatlist on iOS.

I found a workaround for this bug by following the second answer to this question on StackOverflow: https://stackoverflow.com/questions/30626030/can-you-force-a-react-component-to-rerender-without-calling-setstate

I used setTimeout for 100 milliseconds in the ComponentDidMount function to execute the setState. The solution will refresh the Swiper so that the images appear on Android without having to re-render everything.

I had to add a delay to get mine to work, but yes it works!

  constructor(props) {
    super(props);
    this.state = { showSwiper: false };
  }

  componentDidMount() {
    // Must use this 100-ms delayed swiper workaround to render on Android properly
    setTimeout(() => {
      this.setState({showSwiper: true});
    }, 100);
  }

  render() {
    var exampleSwiper = (
      <Swiper activeDotColor={'white'} loop={false} >
        <View style={{width: 100, height: 100, backgroundColor: 'white'}} />
        <View style={{width: 100, height: 100, backgroundColor: 'white'}} />
        <View style={{width: 100, height: 100, backgroundColor: 'white'}} />
      </Swiper>
    );
    return (
      <Modal presentationStyle={'overFullScreen'}>
        {this.state.showSwiper ? exampleSwiper : null}
      </Modal>
    );
  }

I have the same issue on the Android.

@MM-Psiiirus @arminsal1 i tried the suggested solution but it didn’t work for me. So what happens is that when I load quite a lot of images (say 5 and more), some images get displayed and some don’t. My codes:

        <Modal
          animationType={"slide"}
          transparent={false}
          visible={this.state.modalVisible}
          onRequestClose={() => {
            this.setState({modalVisible: false});
          }}
          >
          <Swiper key={this.state.swiper_key} showsButtons={true}>
            {this.state.chosen_image.map((image, i) => 
              this.renderSwiperView(image, i)
            )}
          </Swiper>
        </Modal>
  renderSwiperView(image, key) {
    return (
      <View style={{flex: 1}} key={key}>
        <PhotoView
          key={key}
          source={{uri: image.path}}
          minimumZoomScale={1}
          maximumZoomScale={3}
          onLoad={() => console.log("Image loaded!")}
          resizeMode={'contain'}
          style={{flex: 1}} />
      </View>
    );
  }

Right after I loaded the state variable ‘chosen_image’ with array of images, I use this.setState({swiper_key: Math.random()}) to re-render the swiper. However, some images fail to display

FYI: i’ve fixed it by just add an unique key to my swiper <Swiper key={myUniqueId} />