Reputation: 928
I use a FlatList
component for images grid because it have a good performance:
<FlatList
data={photos}
columnWrapperStyle={styles.listColumn}
numColumns={4}
renderItem={photo => this.renderPhoto(photo)}
/>
For now renderPhoto
func return a new FastImage component (i use it because it have a cool caching feature)
<FastImage
resizeMode={FastImage.resizeMode.cover}
source={{uri: photo.src}}
/>
In the end I have something like this:
But now I want to have a very familiar possibility. Tap on the image will start the animation after which the image will be stretched to the full width of the screen.
After that, the user can do the following:
FlatList
It might look something like this:
So, whats a problem?
All existing carousel solutions are a wrapper for an image collection. But I cant pass wrapper component inside FlatList
.
I could not find a ready-made component for solving such a common problem.
There are some that I try to combine (Lightbox, Carousel). But this solution will greatly affect performance. (I need to load the entire collection of images from the FlatList
into the carousel component) In addition, such solutions usually have problems with animation.
So I'm wondering if there really is no react-native
solution for such a popular image view mechanics?
Perhaps it is worth making a native module on the swift
/objc
(FlatList of images with carousel modal)?
Upvotes: 2
Views: 7423
Reputation: 74
Actually is possible with the elements that you have.
First you have the carousel (react-native-looped-carousel):
const activeProps = {
resizeMode: 'contain',
flex: 1,
width: null
};
const { height, width } = Dimensions.get('window');
const renderCarousel = (album, currentPage) => (
<Carousel style={{ width, height }} currentPage={currentPage} autoplay={false}>
{album.map(image => (
<FastImage
style={{ flex: 1 }}
resizeMode={FastImage.resizeMode.contain}
source={{ uri: image.uri }}
key={image.uri}
/>))
}
</Carousel>
);
Then FastImage (react-native-fast-image) with the lightbox (react-native-lightbox):
LightImage = (props) => {
const currentPage = this.items.findIndex(x => x.uri === props.source.uri);
return (
<Lightbox
activeProps={activeProps}
renderContent={() => renderCarousel(this.items, currentPage)}
>
<FastImage {...props} />
</Lightbox>
);
}
Now you can use your renderItem with the component for the FastImage and Lightbox
<FlatList
data={this.items}
columnWrapperStyle={styles.listColumn}
numColumns={4}
renderItem={photo => this.LightImage(photo)}
/>
I've copied part of my code, so it won't work with just copy and paste. If you have any question feel free to ask! There's only one problem with this implementation that if you rotate the device the layout breaks
Upvotes: 2