react-native-grid-image-viewer
Version:
A grid display for multiple images which you can view on clicking in fullscreen mode and swipe through.
260 lines (246 loc) • 7.83 kB
JavaScript
import React, {useState, useRef, useEffect} from 'react';
import {
View,
StyleSheet,
Dimensions,
TouchableOpacity,
Modal,
FlatList,
Image,
ScrollView,
Platform,
NativeModules,
BackHandler,
} from 'react-native';
import Cross from './Cross';
const GridImageView = ({
data,
headers = null,
renderGridImage = null,
renderModalImage = null,
transparent = 0.8,
heightOfGridImage = Dimensions.get('window').height / 5.5,
}) => {
const [modal, setModal] = useState({visible: false, data: 0});
const ref = useRef();
var key = 0;
const {StatusBarManager} = NativeModules;
const STATUSBAR_HEIGHT =
Platform.OS === 'ios' ? 20 : StatusBarManager.HEIGHT - 20;
const [height, setHeight] = useState(STATUSBAR_HEIGHT);
const onCloseModal = () => {
setModal({visible: false, data: 0});
};
useEffect(() => {
if (Platform.OS === 'ios') {
StatusBarManager.getHeight((statusBarHeight) => {
setHeight(statusBarHeight.height);
});
}
BackHandler.addEventListener('hardwareBackPress', onCloseModal);
return () => {
BackHandler.removeEventListener('hardwareBackPress', onCloseModal);
};
}, []);
const Component = ({style = {flex: 1}}) => {
return (
<ScrollView
showsHorizontalScrollIndicator={false}
ref={ref}
style={{...style}}
snapToInterval={Dimensions.get('window').width}
decelerationRate="fast"
pagingEnabled
horizontal>
{data.map((item, key) => (
<View key={key}>
{renderModalImage !== null ? (
renderModalImage(item, {
...styles.img_modal,
backgroundColor: `rgba(0, 0, 0, ${transparent})`,
})
) : (
<Image
style={{
...styles.img_modal,
backgroundColor: `rgba(0, 0, 0, ${transparent})`,
}}
source={{
uri: item,
...(headers == null || headers == undefined || headers == {}
? {}
: {method: 'POST', headers}),
}}
/>
)}
</View>
))}
</ScrollView>
);
};
return (
<View style={styles.background}>
<Modal
// propagateSwipe={true}
animationType="slide"
transparent={true}
visible={modal.visible}
onRequestClose={onCloseModal}>
<Component />
<View style={{...styles.cross, top: height + 5}}>
<TouchableOpacity
onPress={() => {
setModal({visible: false, data: 0});
}}>
<Cross />
</TouchableOpacity>
</View>
</Modal>
<FlatList
contentContainerStyle={{paddingBottom: 40}}
data={data}
renderItem={({index}) => {
if (data.length <= index * 3) {
return null;
}
return (
<View style={styles.unit}>
<View style={[styles.unit_item, {height: heightOfGridImage}]}>
{data.length > index * 3 ? (
<TouchableOpacity
onPress={() => {
setModal({visible: true, data: index * 3});
setTimeout(() => {
ref.current.scrollTo({
x: Dimensions.get('window').width * index * 3,
y: 0,
animated: false,
});
}, 1);
}}
style={[styles.unit_item, {height: heightOfGridImage}]}>
{renderGridImage !== null ? (
renderGridImage(data[index * 3], styles.img)
) : (
<Image
style={styles.img}
source={{
uri: data[index * 3],
...(headers == null ||
headers == undefined ||
headers == {}
? {}
: {method: 'POST', headers}),
}}
/>
)}
</TouchableOpacity>
) : null}
</View>
<View style={[styles.unit_item, {height: heightOfGridImage}]}>
{data.length > index * 3 + 1 ? (
<TouchableOpacity
onPress={() => {
setModal({visible: true, data: index * 3 + 1});
setTimeout(() => {
ref.current.scrollTo({
x: Dimensions.get('window').width * (index * 3 + 1),
y: 0,
animated: false,
});
}, 1);
}}
style={[styles.unit_item, {height: heightOfGridImage}]}>
{renderGridImage !== null ? (
renderGridImage(data[index * 3 + 1], styles.img)
) : (
<Image
style={styles.img}
source={{
uri: data[index * 3 + 1],
...(headers == null ||
headers == undefined ||
headers == {}
? {}
: {method: 'POST', headers}),
}}
/>
)}
</TouchableOpacity>
) : null}
</View>
<View style={[styles.unit_item, {height: heightOfGridImage}]}>
{data.length > index * 3 + 2 ? (
<TouchableOpacity
onPress={() => {
setModal({visible: true, data: index * 3 + 2});
setTimeout(() => {
ref.current.scrollTo({
x: Dimensions.get('window').width * (index * 3 + 2),
y: 0,
animated: false,
});
}, 1);
}}
style={[styles.unit_item, {height: heightOfGridImage}]}>
{renderGridImage !== null ? (
renderGridImage(data[index * 3 + 2], styles.img)
) : (
<Image
style={styles.img}
source={{
uri: data[index * 3 + 2],
...(headers == null ||
headers == undefined ||
headers == {}
? {}
: {method: 'POST', headers}),
}}
/>
)}
</TouchableOpacity>
) : null}
</View>
</View>
);
}}
keyExtractor={(item) => {
key++;
return key.toString();
}}
style={styles.flatlist}
/>
</View>
);
};
const styles = StyleSheet.create({
background: {
flex: 1,
},
flatlist: {
flex: 1,
},
unit: {
flexDirection: 'row',
},
unit_item: {
margin: 1.5,
flex: 1,
},
img: {
flex: 1,
},
img_modal: {
height: Dimensions.get('window').height,
width: Dimensions.get('window').width,
resizeMode: 'contain',
},
cross: {
position: 'absolute',
alignSelf: 'center',
alignItems: 'center',
justifyContent: 'center',
left: 0,
},
});
export default GridImageView;