Open In App

Create an Image/Video Gallery using React-Native

Last Updated : 05 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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

preview image of image/video gallery app

Prerequisites and Technolgies Used

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:

Screenshot-2023-12-03-081717

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.

Javascript




// App.js
 
import { 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:

screenrec_33



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads