This tutorial is the third part of our React Native Car Parking App UI clone series. In the previous part, we successfully implemented the scrolling transition of car parking spots. In this tutorial, we are going to continue from where we left off in the last part. So, it is recommended to go through the previous part in order to get the full insight into the project.
As stated in the previous parts, the tutorial series was inspired by the React Native App Templates that provides us with a dynamic, fully-coded starter kit written in React Native that anyone can use to build their own store locator React Native application or initiate their own startup.
And, this third part is also the continuation of coding implementations and designs from the Youtube video tutorial by React UI Kit for the Camping Spots Finder App clone. The video tutorial uses the fast coding technique to implement this UI clone which may be difficult to grasp for any developer especially the beginners. This written tutorial provides the step by step implementation which will be easier to understand and implement.
In this third part of this tutorial series, we are going to add additional information to our parking spot cards of the parking section in the map screen as well as style it correctly. The idea is to integrate the car parking spot data into the parking spot card that we implemented with the scrolling transition in the last tutorial. Then, we are going to add some components and button styles to the card as well in order for it to look appealing. We are also going to use vector icons and style them properly.
So, let us begin!!
Here, we are going to add some additional car parking spot information to our parking spot card in the parking section. We are also going to style it in order for it to look appealing. Now, we are going to use some additional data from parkingsSpots array and use it in the renderParking() method as shown in the code snippet below:
renderParking(item){
return(
<View key={`parking-${item.id}`} style={styles.parking}>
<View style={{flex : 1, flexDirection : 'column'}}>
<Text>x {item.spots} {item.title}</Text>
</View>
<View style={{flex : 1}}>
<Text>${item.price}</Text>
<Text>{item.rating}</Text>
</View>
</View>
)
}
Here, we have the parent
View
component wrapping two child View
components. The first child View component has some inline styles with spots and title information. And, the second View
component has price and rating information. The required style is provided in the code snippet below:
parking : {
flexDirection : 'row',
backgroundColor : 'white',
borderRadius : 6,
padding : 24,
marginHorizontal: 24,
width : width - ( 24 * 2 )
}
Hence, we will get the following result in our emulator screen:
As we can see, some additional parking spot information has appeared on the parking spot card. But, we need to add more information from our parkingsSpots array.
Here, we are going to add the time value for each parking spot cards. For that, we need to define a state called hours as shown in the code snippet below:
state = {
hours: {},
}
Now, we need to add additional information to our parking spot card from renderParking() method as shown in the code snippet below:
renderParking(item){
const { hours } = this.state;
return(
<View key={`parking-${item.id}`} style={styles.parking}>
<View style={{flex : 1, flexDirection : 'column'}}>
<Text>x {item.spots} {item.title}</Text>
</View>
<View style={{flex : 1}}>
<Text>${item.price}</Text>
<Text>{item.rating}</Text>
<TouchableWithoutFeedback>
<View style={styles.buy}>
<View>
<Text>${item.price *2}</Text>
<Text>{item.price}x{hours[item.id]} hrs</Text>
</View>
<View>
<Text></Text>
</View>
</View>
</TouchableWithoutFeedback>
</View>
</View>
)
}
Here, we have the
TouchableWithoutFeedback
component from the react-native package just below the rating Text
component. Inside the TouchableWithoutFeedback
component, we have added some View
and Text
components to display the price and price per time in our parking spot cards. This TouchableWithoutFeedback
component is added in order to implement a button.Note that, we should not forget to import the TouchableWithoutFeedback from the react-native package.
The required style for this is provided in the code snippet below:
buy: {
flex: 1,
backgroundColor : 'red'
},
Hence, we will get the following screen in our android emulator:
As we can see, we have the section with a red background color in our parking spot card. In this red section shown in the above screenshot, we are going to implement the button. Therefore, the overall style of the parking spot card does not look appealing. We need to configure it with more styles in other to make it appear attractive.
Here, we are going to add various style properties to the components in the renderParking() method. The styles are inline as well as in the
StyleSheet
component. The overall coding implementation for configuring styles in renderParking() method is provided in the code snippet below:renderParking(item){
const { hours } = this.state;
return(
<View key={`parking-${item.id}`} style={styles.parking}>
<View style={{flex : 1, flexDirection : 'column'}}>
<Text style={{fontSize: 16}}>x {item.spots} {item.title}</Text>
</View>
<View style={{flex : 1, flexDirection : 'row'}}>
<View style={{flex : 1, justifyContent: 'center'}}>
<Text>${item.price}</Text>
<Text>{item.rating}</Text>
</View>
<TouchableWithoutFeedback>
<View style={styles.buy}>
<View style={{flex:1, justifyContent: 'center'}}>
<Text style={{fontSize : 25, color : 'white'}}>${item.price *2}</Text>
<Text style={{ color : 'white'}}>{item.price}x{hours[item.id]} hrs</Text>
</View>
<View style={{flex : 0.5, justifyContent : 'center', alignItems : 'center'}}>
<Text style={{fontSize: 25, color : 'white'}}>></Text>
</View>
</View>
</TouchableWithoutFeedback>
</View>
</View>
)
}
Here, we have also added an additional
View
component inside the TouchableWithoutFeedback
component in order to display a ‘greater than’ sign. All the components are bound to some inline style properties which contain flex as well as font style properties. The required styles in the
StyleSheet
component are provided in the code snippet below: parking: {
flexDirection : 'row',
backgroundColor : 'white',
borderRadius : 6,
padding : 20,
marginHorizontal: 24,
width : width - ( 24 * 2 )
},
buy: {
flex: 1,
flexDirection : 'row',
padding : 8,
borderRadius : 6,
backgroundColor : 'red'
},
Hence, we will get the following result in our android emulator screen:
As we can see, our parking spot card looks better now. All the information that we need is in the proper position.
Now, we are going to add the hour section to the card.
In the actual app, this hour section is used to select the time based on hours. The hours represent the time for which users are going to park in that parking spot. Here, we are only going to implement a single time in the hours section for UI. Later in upcoming tutorials, we will also implement the time picker for the hours section. Now, in order to add the hour’s section to the parking spot card, we need to use the code from the following code snippet:
<View style={{flex : 1, flexDirection : 'column'}}>
<Text style={{fontSize: 16}}>x {item.spots} {item.title}</Text>
<View style={{width : 100, borderRadius : 6, borderColor : 'grey', borderWidth : 0.7, padding : 4}}>
<Text style={{fontSize : 16}}>05:00 hrs</Text>
</View>
</View>
Here, we have added the additional
View
component inside our first child View
component of the renderParking() method. This View
component wraps the Text
component with text representing time. The View
and Text
component are going with some inline styles to give them a proper look.Now, we remember that we added a
TouchableWithoutFeedback
component before in renderParking() method. Now, we are going to replace that TouchableWithoutFeedback
component with TouchableOpacity
component so that when we click on the button it gives off some fading effect. The code for this is available in the code snippet below: <TouchableOpacity style={styles.buy}>
<View style={{flex:1, justifyContent: 'center'}}>
<Text style={{fontSize : 25, color : 'white'}}>${item.price *2}</Text>
<Text style={{ color : 'white'}}>{item.price}x{hours[item.id]} hrs</Text>
</View>
<View style={{flex : 0.5, justifyContent : 'center', alignItems : 'center'}}>
<Text style={{fontSize: 25, color : 'white'}}>></Text>
</View>
</TouchableOpacity>
Here, we have also removed the
View
component that was wrapping the rest of the component inside the TouchableOpacity
component. The style provided to that View
component is now bound to the TouchableOpacity
component.Note that, we should not forget to import the TouchableOpacity from the react-native package.
Hence, we will get the following result in our emulator screen:
As we can see, we have got the hours section in our parking spot card. And, now the button at the right-hand side is also clickable with fading effect.
Now, we need to add some icons to our parking spot cards.
Adding Icons
Here, we are going to add some icons to our parking spot cards. These icons will represent some information from the parkingsSpots array data. Adding icons will make the parking spot cards even for appealing. For that, we need to import the vector icons package first. Since this project was created using expo, the vector icons package is provided by default by the expo. Now, we need to import the vector icons package from the expo package as shown in the code snippet below:
import { FontAwesome, Ionicons } from '@expo/vector-icons';
This expo packager for vector icons uses the react-native-vector-icons package. Here, we have imported the
FontAwesome
as well as Ionicons icon packages.Now, we are going to add these icon components to our renderParking() method as shown in the code snippet below:
<View style={{flex : 1.5, flexDirection : 'row'}}>
<View style={{flex : 0.5, justifyContent: 'center', marginHorizontal : 24}}>
<View style={{flex: 1, flexDirection : 'row', justifyContent : 'space-between', alignItems : 'center'}}>
<Ionicons name='ios-pricetag' size={16} color="#70818A"/>
<Text>${item.price}</Text>
</View>
<View style={{flex: 1, flexDirection : 'row', justifyContent : 'space-between', alignItems : 'center'}}>
<Ionicons name='ios-star' size={16} color="#70818A"/>
<Text>{item.rating}</Text>
</View>
</View>
<TouchableOpacity style={styles.buy}>
<View style={{flex:1, justifyContent: 'center'}}>
<Text style={{fontSize : 25, color : 'white'}}>${item.price *2}</Text>
<Text style={{ color : 'white'}}>{item.price}x{hours[item.id]} hrs</Text>
</View>
<View style={{flex : 0.5, justifyContent : 'center', alignItems : 'center'}}>
<Text style={{fontSize: 25, color : 'white'}}>></Text>
</View>
</TouchableOpacity>
</View>
Here, we have additional
View
components that wrap the Ionicons components as well as Text component for rating and price. The View
components are bound to some inline styles having flex properties. Some changes are made to style variables which are provided in the code snippet below:parking: {
flexDirection : 'row',
backgroundColor : 'white',
borderRadius : 6,
padding : 15,
marginHorizontal: 24,
width : width - ( 24 * 2 )
},
buy: {
flex: 1.25,
flexDirection : 'row',
padding : 8,
borderRadius : 6,
backgroundColor : '#D83C54'
},
Hence, we will get the following result in our emulator screen:
As we can see, we have got icons in our parking spot card which represents the price and rating. This makes our parking spot card in the parking section more attractive.
Now for the convenience, the entire coding implementation in renderParking() method till now is provided in the code snippet below:
renderParking(item){
const { hours } = this.state;
return(
<View key={`parking-${item.id}`} style={styles.parking}>
<View style={{flex : 1, flexDirection : 'column'}}>
<Text style={{fontSize: 16}}>x {item.spots} {item.title}</Text>
<View style={{width : 100, borderRadius : 6, borderColor : 'grey', borderWidth : 0.7, padding : 4}}>
<Text style={{fontSize : 16}}>05:00 hrs</Text>
</View>
</View>
<View style={{flex : 1.5, flexDirection : 'row'}}>
<View style={{flex : 0.5, justifyContent: 'center', marginHorizontal : 24}}>
<View style={{flex: 1, flexDirection : 'row', justifyContent : 'space-between', alignItems : 'center'}}>
<Ionicons name='ios-pricetag' size={16} color="#70818A"/>
<Text>${item.price}</Text>
</View>
<View style={{flex: 1, flexDirection : 'row', justifyContent : 'space-between', alignItems : 'center'}}>
<Ionicons name='ios-star' size={16} color="#70818A"/>
<Text>{item.rating}</Text>
</View>
</View>
<TouchableOpacity style={styles.buy}>
<View style={{flex:1, justifyContent: 'center'}}>
<Text style={{fontSize : 25, color : 'white'}}>${item.price *2}</Text>
<Text style={{ color : 'white'}}>{item.price}x{hours[item.id]} hrs</Text>
</View>
<View style={{flex : 0.5, justifyContent : 'center', alignItems : 'center'}}>
<Text style={{fontSize: 25, color : 'white'}}>></Text>
</View>
</TouchableOpacity>
</View>
</View>
)
}
As a result, our result till now is shown in the emulator simulation below:
Finally, we have successfully completed the implementation and styling of parking spot cards in our React Native Car Parking Finder App UI Clone. With this, we have come to the end of this part of our tutorial.
This tutorial is the third part of the React Native Car Parking Finder App UI clone tutorial series. In this part, we continued from where we left off in the second part of this tutorial series. In this part of the tutorial, we successfully added the additional parking spot information from the data array. Then, we configured styles as well as various react-native components in order to give the parking spot card its proper look. Lastly, we got an insight into how to use the vector icons package provided by the expo package.
In the next part of this tutorial series, we are going to add the Map Marker which will represent different parking spots on the map.