Last Updated : 23 Jul, 2024
Summarize
Comments
Improve
An Image/Video Gallery is a common feature in mobile applications. This article will guide you for creating an Image/Video Gallery using React Native.We will learn to build an Image/Video Gallery app using React-Native. In this app, we will display the images and videos in the form of a grid, and on clicking, we can view them. If an image is clicked, the image viewer is opened, similarly, if a video is clicked, a video player is launched. By the end of this tutorial, you will have solid understanding of MediaLibrary usage in React Native.
Preview of final output: Let us have a look at how the final output will look like
Prerequisites and Technolgies Used
- Introduction to React Native
- Introduction React Native Components
- React Native State
- React Native Props
- Expo CLI
- Node JS and npm (Node Package Manager)
Approach to create Image/Video Gallery App
- The application will be single page app.
- It will contain two types, image and video so we used useState hook with default value of image.
- Using the FlatList component, we load the assets from MediaLibrary. It gets the permission from user in the device.
- On getting the assets, we display the image and videos in different tabs using Buttons.
- We wrap the images with Pressable. On clicking, we set the file location .
- The Modal component becomes visible on setting the imageName variable. Here we check if image, we display an image, else video.
Steps to create the project:
Step 1: Create the project:
npx create-expo-app image-video-gallery-app
Step 2: Navigate to the project
cd image-video-gallery-app
Step 3: Install the required libraries
npx expo install expo-av
npx expo install expo-image
npx expo install expo-media-library
Step 4: Configuration in app.json/app.config.js
{
"expo": {
"plugins": [
[
"expo-media-library",
{
"photosPermission": "Allow $(name) to access your photos.",
"savePhotosPermission": "Allow $(name) to save photos.",
"videosPermission": "Allow $(name) to access your videos.",
"isAccessMediaLocationEnabled": true
}
]
]
}
}
Project Structure:
The updated dependencies in package.json file will look like:
"dependencies": {
"expo": "~49.0.15",
"expo-status-bar": "~1.6.0",
"react": "18.2.0",
"react-native": "0.72.6",
"expo-media-library": "~15.4.1",
"expo-image": "~1.3.5",
"expo-av": "~13.4.1"
},
"devDependencies": {
"@babel/core": "^7.20.0"
}
Example: In this example we are following the above-explained approach.
// App.jsimport { StatusBar } from "expo-status-bar";import { Button, FlatList, Modal, Pressable, ScrollView, StyleSheet, Text, View,} from "react-native";import * as MediaLibrary from "expo-media-library";import { useState } from "react";import { Image } from "expo-image";import { Video, ResizeMode } from "expo-av";export default function App() { const [galleryFiles, setGalleryFiles] = useState([]); const [currentImage, setCurrentImage] = useState(""); const [mediaType, setMediaType] = useState("image"); const fetchMedia = async (first, mediaType) => { const { status } = await MediaLibrary.requestPermissionsAsync(); if (status === "granted") { const media = await MediaLibrary.getAssetsAsync({ first: first + 30, sortBy: MediaLibrary.SortBy.creationTime, mediaType: mediaType === "image" ? MediaLibrary.MediaType.photo : MediaLibrary.MediaType.video, }); setGalleryFiles(media.assets); } }; const renderItem = ({ item }) => ( <View style={styles.imageContainer}> <Pressable onPress={() => { setCurrentImage(item.uri); setMediaType(item.mediaType); }} > <Image source={{ uri: item.uri }} style={{ width: 200, height: 200 }} /> </Pressable> </View> ); return ( <View style={styles.container}> <StatusBar style="auto" /> <Text style={styles.heading}>Welcome to GeeksforGeeks</Text> <View style={{ flexDirection: "row", justifyContent: "space-around", width: "100%", padding: 10, }} > <Button title="Images" onPress={() => { setMediaType("image"); fetchMedia(0, "image"); }} /> <Button title="Videos" onPress={() => { setMediaType("video"); fetchMedia(0, "video"); }} /> </View> {/* view full image in modal */} <Modal visible={currentImage !== ""} transparent={false}> <View style={{ flex: 1, backgroundColor: 0 }}> <Pressable style={{ position: "absolute", top: 40, zIndex: 1, flex: 1, alignSelf: "center", }} title="Close" onPress={() => setCurrentImage("")} > <Text style={{ color: "black", fontSize: 20, padding: 10, backgroundColor: "white", }} > Close </Text> </Pressable> {mediaType === "video" ? ( <Video style={{ width: "100%", height: "100%", }} source={{ uri: currentImage, }} useNativeControls resizeMode={ResizeMode.CONTAIN} isLooping /> ) : ( <Image source={{ uri: currentImage }} style={{ width: "100%", height: "100%" }} /> )} </View> </Modal> <View style={styles.scrollContainer}> <Text style={{ fontSize: 20, marginBottom: 20 }}> My Gallery </Text> <FlatList data={galleryFiles} renderItem={renderItem} keyExtractor={(item) => item.id} numColumns={3} onEndReached={() => { fetchMedia(galleryFiles.length, mediaType); }} onLayout={() => { fetchMedia(galleryFiles.length, mediaType); }} /> </View> </View> );}const styles = StyleSheet.create({ container: { flex: 1, justifyContent: "center", alignItems: "center", marginTop: "10%", }, scrollContainer: { flex: 1, marginTop: 20, width: "100%", }, heading: { color: "green", fontSize: 30, textAlign: "center", fontWeight: "bold", }, imageContainer: { flex: 1, margin: 1, aspectRatio: 1, // This ensures that images maintain their aspect ratio borderRadius: 8, overflow: "hidden", }, image: {},});
Steps to run the application:
Step 1: Navigate to the terminal or command prompt and type the required command there to run the React native application.
npx expo start
Step 2: Depending on your operating system, type the following command in terminal
- To run on Android:
npx react-native run-android
- To run on Ios:
npx react-native run-ios
Step optional: To run on Web, you need to install the following packages
npx expo install react-dom react-native-web @expo/webpack-config
Step 3: To run on web, press w on Terminal will application is running. For Android/IOS, install the Expo app and scan the QR code or enter the link of Metro in the Terminal.
Output:
Next Article
Create an Image/Video Downloader App using React-Native