react-native-image-gallery icon indicating copy to clipboard operation
react-native-image-gallery copied to clipboard

Too many images crash

Open Draccan opened this issue 6 years ago • 8 comments

Hi,

I have to report a problem and I hope that someone could help me.

Every time I have more than 90 images and I want to open one image using InitialPage prop the component blocks showing another image (often the third image). In this scenario I cannot swipe, but the app is not blocked. I can close the gallery modal and navigate in my app.

Is there a way to solve this issue?

Important: this happen only on Android.

Draccan avatar Apr 18 '18 08:04 Draccan

Ok guys. I have found a solution that works perfectly in my specific case where I know that I want to show images full width.

This is my code: <Gallery style={{ flex: 1, backgroundColor: 'black' }} images={this.state.imageUrls} initialPage = {this.state.selectedImageIndex} flatListProps={ { initialNumToRender: 20, initialScrollIndex:this.state.selectedImageIndex, getItemLayout: (data, index) => ({length: Dimensions.get('screen').width, offset: Dimensions.get('screen').width * index, index}) } }/>

I have something like 100 images in this.state.imageUrls (all cached local images..). I set an initialPage because user see 100 thumbnails and when taps on an image I want to display the gallery starting from the image selected. At the end I use the flatList props: initialNumToRender is not mandatory, however I have seen that there is no such memory consumption. I set the initialScrollIndex even if I think that the component already does it when I set initialPage. Most important thing I set the getItemLayout prop. Both Android and iOS works perfectly without strange blocks.

Draccan avatar Apr 18 '18 08:04 Draccan

+1 this works!

ddxxtony avatar Apr 18 '18 14:04 ddxxtony

FYI: This doesn't seem to work well when changing orientation in the slideshow view. The offset will need to be recalculated and I lost swipe functionality.

geirman avatar Apr 27 '18 15:04 geirman

@geirman Yes, I haven't tried with orientation changing. The app I have developed is portrait-only.

I understand your problem: one way to solve it could be to block orientations while swiping images. I can't imagine a way to calculate again the offset without an activity indicator in the front of the screen. I really think that it would be really slow with more than 50 images more or less.

I hope someone else could find a solution for your problem :)

Draccan avatar Apr 27 '18 15:04 Draccan

Yah, thanks... it's not really a big problem for me. It works well without the layout calculations in 2.1.4. The only problem I get during orientation change is that the index && index+1 images flash briefly before index fills the screen.

My app is locked to portrait except for the gallery slider. When an image is landscape oriented, it's helpful to flip the phone on it's side to see the entire image.

geirman avatar Apr 27 '18 15:04 geirman

@geirman may i ask what code are you using for the orientation change when you are locked to portrait?

sicsol avatar Apr 27 '18 17:04 sicsol

@sicsol here's the relevant code 💯

import { ScreenOrientation } from 'expo';
componentWillMount() {
    ScreenOrientation.allow(ScreenOrientation.Orientation.ALL_BUT_UPSIDE_DOWN);
  }

  componentWillUnmount() {
    ScreenOrientation.allow(ScreenOrientation.Orientation.PORTRAIT);
  }

geirman avatar Apr 27 '18 18:04 geirman

I think this library should default to some sane values to avoid crashes. This is a gallery component after all, so it's to be expected that it will be showing a lot of items.

Here's what I went through after reading above comments: Adding windowSize: 1, intialNumToRender: 1 avoided a crash but then swiping and pinching did not work. Selected image was just statically displayed. Adding getItemLayout would cause a crash. No image was ever fully displayed. Adding maxToRenderPerBatch made everything work again. Swiping, pinching now works.

initialScrollIndex makes no difference for memory consumption.

This is my resulting code:

<Gallery
  style={styles.gallery}
  images={images}
  flatListProps={{
    windowSize: 3, // limits memory usage to 3 screens full of photos (ie. 3 photos)
    initialNumToRender: 3, // limit amount, must also be limited, is not controlled by other props
    maxToRenderPerBatch: 2, // when rendering ahead, how many should we render at the same time
    getItemLayout: (data, index) => ({ // fixes scroll and pinch behavior
      length: Dimensions.get('screen').width,
      offset: Dimensions.get('screen').width * index,
      index,
    }),
  }}
  removeClippedSubviews
  initialPage={initialPage > 0 ? initialPage : 0}
/>

Setup: My test-device was an iPhone 5C. Many other iPhone modals will have similar RAM amounts, so values far beyond what I've given as example above may work for your particular gallery but be careful, as your app may then be chosen for elimination more if user uses app-switcher. I was attempting to show a gallery of 34 photos taken with the camera, but just showing 1 photo at a time.

scarlac avatar Apr 11 '19 22:04 scarlac