React-native-swiper: Images not loading on Android

Created on 5 Apr 2017  路  15Comments  路  Source: leecade/react-native-swiper

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

Most helpful comment

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

All 15 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.

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

@MM-Psiiirus but after reload, it hide again...

@ayACEP odd maybe it is your content? ...the key={myUniqueId} should force a total rerendering which should solve the "bug".

@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

This stupid error still exists today on Android

@arminsal1 setTimeOut 100ms didn't work, because it depends on how many time it take to load the view.

after 2 days stuck at this issue, I had success when added the same images of "app/images" directory in the "android/app/src/main/res/drawable-mdpi/" path with the prefix "app_images_".
So: app/images/test.png was also added at android/app/src/main/res/drawable-mdpi/app_images_test.png and it worked

What worked for me was to add a condition to the Swiper, making sure that the array you want to render was already created. For example in the render function: { !!this.props.imageArray.length && <Swiper /> }

+1, same here, any solution?

same problem, any solution ?

I have the same issue on the Android.

+1

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>
    );
  }
Was this page helpful?
0 / 5 - 0 ratings

Related issues

tokict picture tokict  路  3Comments

ghost picture ghost  路  3Comments

kliuj picture kliuj  路  3Comments

chetanparakh picture chetanparakh  路  3Comments

hadrienbbt picture hadrienbbt  路  3Comments