Creating a React Native App with Animated Splash Screen

Yildizfatma
4 min readAug 23, 2023

--

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

  1. Setting Up the Project
  2. Implementing the Animated Splash Screen
  3. Fetching and Displaying Product Data
  4. 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

--

--