Creating a React Native App with Animated Splash Screen
Today,we’ll walk through the process of building a React Native app that features an animated splash screen. The app will display a list of jewelry products fetched from an API and allow users to view detailed information about each product. Let’s get started!
Table of Contents
- Setting Up the Project
- Implementing the Animated Splash Screen
- Fetching and Displaying Product Data
- Displaying Detailed Product Information
1. Setting Up the Project
We’ll begin by setting up a new React Native project and installing the necessary dependencies.
npx react-native init JewelryApp
cd JewelryApp
npm install @react-navigation/native @react-navigation/native-stack axios expo-font
2. Implementing the Animated Splash Screen
First, let’s create the SplashScreen
component that will be displayed while the app is loading.
// SplashScreen.js
import React from 'react';
import { View, Image, StyleSheet, Animated } from 'react-native';
const SplashScreen = () => {
const imageScale = new Animated.Value(0.1);
Animated.timing(imageScale, {
toValue: 1,
duration: 1000,
useNativeDriver: true,
}).start();
return (
<View style={styles.container}>
<Animated.Image
source={require('../assets/ring1.png')}
style={[styles.image, { transform: [{ scale: imageScale }] }]}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white',
},
image: {
width: 400,
height: 400,
},
});
export default SplashScreen;
//app.js
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import FirstPage from './screens/FirstPage';
import SecondPage from './screens/SecondPage';
import SplashScreen from './screens/SplashScreen';
import { useState,useEffect } from 'react';
const Stack= createNativeStackNavigator();
export default function App() {
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
// Simulate loading process
setTimeout(() => {
setIsLoading(false);
}, 2000); // Adjust the time as needed
}, []);
return (
<NavigationContainer>
{isLoading ? <SplashScreen /> : <Stack.Navigator
screenOptions={{ headerShown: false }}>
<Stack.Screen name="FirstPage" component={FirstPage} />
<Stack.Screen name="SecondPage" component={SecondPage} />
</Stack.Navigator>}
</NavigationContainer>
);
}
3. Fetching and Displaying Product Data
Now, let’s create the FirstPage
component that fetches and displays a list of jewelry products.
// FirstPage.js
import React, { useState, useEffect } from 'react';
import { View, Text, StyleSheet, FlatList } from 'react-native';
import axios from 'axios';
import ProductBox from '../components/ProductBox';
import { useFonts } from 'expo-font';
const FirstPage = ({ navigation }) => {
const [jewelry, setJewelry] = useState([]);
useEffect(() => {
axios.get("https://fakestoreapi.com/products/category/jewelery")
.then((response) => {
setJewelry(response.data);
})
.catch((error) => {
console.error("Error fetching data:", error);
});
}, []);
const handleSendData = (value) => {
navigation.navigate("SecondPage", {productInfo:value});
};
const renderProductItem = ({item, index})=> (
<View key={index} style={styles.buttonContainer} >
<Text style={styles.buttonText}> {index} </Text>
</View>
);
const [isLoaded] = useFonts({
"titleFont": require('../assets/fonts/Lobster.ttf'),
});
if(!isLoaded){
return null;
};
return(
<View style={styles.mainContainer}>
<Text style={styles.firstPageTitle}> PRODUCTS </Text>
<FlatList
data={jewelery}
keyExtractor={(item) => item.id.toString()}
contentContainerStyle= {styles.flatlistContainer}
handlePressItem= {()=> handleSendData(value.item)}
renderItem={(value)=>
<ProductBox
title={value.item.title}
price={value.item.price}
image={value.item.image}
handlePressProduct={()=> handleSendData(value.item)}
/>}
/>
</View>
);
};
const styles = StyleSheet.create({
mainContainer: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor:'black',
},
firstPageTitle:{
marginTop:82,
color:'white',
fontFamily:'titleFont',
fontSize:33,
},
buttonContainer: {
backgroundColor: 'white',
width:220,
height:200,
padding: 10,
borderRadius: 5,
},
buttonText: {
fontWeight: 'bold',
width: 120,
height: 30,
},
flatlistContainer: {
marginTop:70,
padding: 5,
marginTop:23,
},
});
export default FirstPage;
//SecondPage
import React from 'react';
import { StyleSheet, Text, View, Image, Pressable } from 'react-native';
import { useFonts } from 'expo-font';
const SecondPage = ({ navigation,route }) => {
const handleGoToFirstPage = () => {
navigation.navigate('FirstPage');
};
const [isLoaded] = useFonts({
"titleFont": require('../assets/fonts/Lobster.ttf'),
});
if(!isLoaded){
return null;
};
return (
<View style={styles.productContainer}>
<Image resizeMode='contain' style={styles.imageContainer} source={{ uri: route.params.productInfo.image }} />
<View style={styles.descriptionContainer}>
<Text style={styles.titleContainer}>{route.params.productInfo.title}</Text>
<Text style={styles.priceContainer}>{route.params.productInfo.price}</Text>
<Text style={styles.priceContainer}>{route.params.productInfo.description}</Text>
<Pressable style={styles.button}>
<Text style={styles.buttonText}>Buy Now</Text>
</Pressable>
<Pressable onPress={handleGoToFirstPage} style={styles.button}>
<Text style={styles.buttonText}>Go To Products</Text>
</Pressable>
</View>
</View>
);
};
const styles = StyleSheet.create({
productContainer: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'white',
},
descriptionContainer: {
backgroundColor: 'black',
alignItems: 'center',
flex: 1,
borderRadius: 233,
width: 382,
height: 322,
},
button: {
width: 180,
height: 42,
backgroundColor: 'white',
borderRadius: 44,
marginTop: 11,
},
buttonText: {
color: 'black',
fontFamily: 'titleFont',
fontSize: 24,
textAlign: 'center',
paddingVertical: 6,
},
imageContainer: {
marginTop: 82,
width: 260,
height: 200,
backgroundColor: 'white',
borderRadius: 233,
marginBottom: 24,
},
titleContainer: {
fontWeight: 'bold',
fontSize: 32,
fontFamily: 'titleFont',
color: 'white',
textAlign: 'center',
marginTop: 122,
textAlign: 'center',
padding: 22,
},
priceContainer: {
fontSize: 18,
textAlign: 'center',
color: 'white',
fontFamily: 'titleFont',
},
});
export default SecondPage;
4. Displaying Detailed Product Information
Finally, we’ll create the ProductBox
component to display individual product boxes in the list.
// ProductBox.js
import React from 'react';
import { Pressable, View, Text, Image, StyleSheet } from 'react-native';
const ProductBox = (props) => {
return (
<Pressable
style={styles.container}
onPress={props.handlePressProduct}
>
<View style={styles.infoAndImage}>
<Image
resizeMode='contain'
style={styles.imageStyle}
source={{ uri: props.image }}
/>
<Text numberOfLines={2} style={styles.titleStyle}>{props.title}</Text>
</View>
<View style={styles.productInfoContainer}>
<Text style={styles.priceStyle}>${props.price}</Text>
</View>
</Pressable>
);
};
const styles = StyleSheet.create({
container: {
borderWidth: 0.2,
borderRadius: 5,
width: 370,
height: 130,
alignItems: 'center',
justifyContent: 'space-between',
marginTop: 18,
backgroundColor: 'white',
borderRadius: 53,
paddingHorizontal: 10,
},
// Other styles...
});
export default ProductBox;
I hope, this guide will help you understand how to create a React Native app with an animated splash screen and product listing functionality.
for more you will sucscribe https://www.youtube.com/channel/UCk1Y0ostfs56inRy4yvQtAA
or
instagram:@dev.fatmayildiz