Camping Spots Finder App UI Clone with React Native # 2: List Section
Tags: reactnative, campingspotapp, layout
Published: 2019-10-12 12:17:55

---
title: Camping Spots Finder App UI Clone with React Native # 2: List Section
published: true
date: 2019-10-07 15:53:59 UTC
tags: React native,camping spot app,layout
canonical_url: https://kriss.io/camping-spots-finder-app-ui-clone-with-react-native-2-list-section/
cover_image : https://kriss.io/wp-content/uploads/2019/10/camper.png
---

This tutorial is the second part of our Camping Spots Finder App UI clone using React Native. In the previous part, we successfully implemented the Map view section along with the custom header and header tabs. This tutorial is the continuation of the same tutorial from where we left off in the last part. So, it is suggested to go through the previous parts for better understanding and insight into the overall project.

As stated in the previous part, this inspiration for this tutorial series came from [React native real estate template](https://www.instamobile.io/app-templates/real-estate-app-template-react-native/?ref=4094&campaign=dev.to) that enables us to build fully functional ready to deploy mobile applications that anyone can use to build their own React Native applications. And, this second part is also the continuation of coding implementations and designs from the Youtube video tutorial by [React UI Kit](https://www.youtube.com/watch?v=ScaYmqX15WA&list=PLNRPou200YIeu4UllJkv8-Ca19Ld_eOay&index=14) for the Camping Spots Finder App clone.

In this second part of this tutorial series, we are going to implement the list section that we separated in the previous part of this tutorial as well as set up the navigation to the settings screen.  But first, we are going to make some simple changes to the header section in order to make it look clean and proper. Then, we are going to start implementing the list section and finally add the navigation at the end.

_So, let us begin!!_

## Simple changes to Header Section

First and foremost, we are going to make some simple changes to the header section that includes the custom header and the header tabs. Here, in the Camping.js file `render()` method, we are only going to include the `renderMap()` and `renderList()` method to the ScrollView component. Then, we are going to change the parent `View` component to `SafeAreaView`component and bind the style to it. After that, we are going to include the `renderHeader()` method above the `ScrollView` component as shown in the code snippet below:

```javascript
render(){     
  return (       
   <SafeAreaView style={styles.container}>         
     {this.renderHeader()}         
     <ScrollView style={styles.container}>           
       {this.renderMap()}           
       {this.renderList()}         
     </ScrollView>       
   </SafeAreaView>     
  ); 
}
```

Note that: we need to import the `SafeAreaView` component as well from the react-native package.

Here, we added the SafeAreaView as a parent component because it enables us to render content within the safe area boundaries of a device. However, we need to be careful that this feature only works with the iOS platform. So, we will have to add some extra style in the Android platform in order to achieve the same output as that of `SafeAreaView.`

But first, we are going to wrap the entire template of `renderHeader()` method with another parent `View` component and bind it with extra style. And then, we are going to call the `renderTabs()` method inside this parent `View` component after the `View` component for custom header section as shown in the code snippet below:

```javascript
renderHeader() {
    return (
      <View style={styles.headerContainer}>
        
        <View style={styles.header}>
          <View style={{flex: 2, flexDirection: 'row'}}>
            <View style={styles.settings}>
              <View style={styles.location}>
                <FontAwesome name="location-arrow" size={14} color="white" />
              </View>
            </View>
            <View style={styles.options}>
              <Text style={{ fontSize: 12, color: '#A5A5A5', marginBottom: 5, }}>
                Detected Location
              </Text>
              <Text style={{ fontSize: 14, fontWeight: '300', }}>
                Northern Islands
              </Text>
            </View>
          </View>
          <View style={styles.settings}>
            <TouchableOpacity onPress={() => this.props.navigation.navigate('Settings')}>
              <Ionicons name="ios-settings" size={24} color="black" />
            </TouchableOpacity>
          </View>
        </View> 
        {this.renderTabs()}
      </View>
    )
}
```

Now, we need to add the style `headerContainer` to the Stylesheet component. And the style with its properties is provided below:

```javascript
headerContainer: {
    top: 0,
    marginTop : 20,            //marginTop only in Android platform as SafeAreaView component doesnot work in it
    height: height * 0.15,
    width: width,
}
```

Here, we need to remember to add the `marginTop` style property if we are developing for the Android platform. This is because the `SafeAreaView` component doesn’t work.

Hence, we get the following result in our emulator screen:

![](https://kriss.io/wp-content/uploads/2019/10/Screenshot_1570358335.png)

As we can see, we have the header section with custom header and header tabs in the proper position.

Now, we are going to implement the list section in the `renderList()` method that we defined in the previous tutorial part.

 

## Implementing List Section

In this step, we are going to implement the list section in which there will be different camping spots image and description.

### Including Mock Data

First, we are going to include the mock data for camping spots in an array inside the `renderList()` method. The mock data is provided in the code snippet below:

```javascript
const campings = [
      {
        id: 1,
        type: 'rv',
        name: 'Camping Paradise',
        description: 'Popular spot for trekkers.',
        rating: 4.9,
        distance: 2.9,
        price: 'Free',
        image: 'https://images.unsplash.com/photo-1525811902-f2342640856e?fit=crop&w=900&h=600&q=130',
      },
      {
        id: 2,
        type: 'tent',
        name: 'Lake Florida',
        description: 'This is for all sunset lovers.',
        rating: 4.9,
        distance: 2.9,
        price: 'Free',
        image: 'https://images.unsplash.com/photo-1506535995048-638aa1b62b77?fit=crop&w=900&h=600&q=130',
      },
    ];
```

Here, we have defined the mock data as `campings` array which includes objects with camping spots detail. Now, we will move on to implementing the template for the list section.

### Creating Template Item for List section

Here, we are going to start by implementing a simple template inside the `renderList()` method. The template will contain some `View` and `Text` components with manually entered mock data as shown in the code snippet below:

```javascript
       <View>
          <View>
            <Text>Image</Text>
          </View>
          <View>
            <Text>Camping title</Text>
            <Text>Camping description</Text>
            <View>
              <Text>4.9</Text>
              <Text>2.9 miles</Text>
              <Text>Free</Text>
            </View>
          </View>
          <View>
        </View>
       </View>
```

Hence, we will get the following result in our emulator screen:

![](https://kriss.io/wp-content/uploads/2019/10/Screenshot_1570359054.png)

As we can see, there are no styles and configurations added to it. We are going to do that in the next step.

### Adding proper styles and icons

As the template we created above did not contain any styles, we are going to add some styles to it. Then, we are going to add some icons as well from the `Ionicons` and `FontAwesome` icon packages that we imported in the previous tutorial. We need to add several `flex` style properties as well as add more `View` components with styles to give the list item template a proper look. The code to implement the proper list item template is provided in the code snippet below:

```javascript
<View style={styles.camping}>
        <View>
          <Image />
        </View>
        <View style={styles.campingDetails}>
              <View style={{ flex: 1, flexDirection: 'column', justifyContent: 'center' }}>
                <Text style={{ fontSize: 14, fontWeight: 'bold' }}>
                  Camping title
                </Text>
                <Text style={{ fontSize: 12, color: '#A5A5A5', paddingTop: 5 }}>
                  Camping description
                </Text>
              </View>
              <View style={{ flex: 1, flexDirection: 'row', }}>
                <View style={styles.campingInfo}>
                  <FontAwesome name="star" color="#FFBA5A" size={12} />
                  <Text style={{ marginLeft: 4, color: '#FFBA5A' }}>3.5</Text>
                </View>
                <View style={styles.campingInfo}>
                  <FontAwesome name="location-arrow" color="#FF7657" size={12} />
                  <Text style={{ marginLeft: 4, color: '#FF7657' }}>3.0miles</Text>
                </View>
                <View style={styles.campingInfo}>
                  <Ionicons name="md-pricetag" color="black" size={12} />
                  <Text style={{ marginLeft: 4, color: 'black' }}>Free</Text>
                </View>
              </View>
        </View>
</View>

```

Here, we have a parent `View` component enclosing two child `View` components. The first child `View` component is reserved for `Image` component. The second `View` component is reserved for the details section inside the list item. The second `View` component consists of several child `View` components with style. And these `View` components wrap the `Icon` components as well as `Text` components.

As we can see in the code snippet above, there are several style bindings in each `View` component. Some are inline styles and some are styles from `Stylesheet` component. The style from the `Stylesheet` component is provided in the code snippet below:

```javascript
  camping: {
    flex: 1,
    flexDirection: 'row',
    borderBottomColor: '#A5A5A5',
    borderBottomWidth: 0.5,
    padding: 20,
  },
  campingDetails: {
    flex: 2,
    paddingLeft: 20,
    flexDirection: 'column',
    justifyContent: 'space-around',
  },
  campingInfo: {
    flexDirection: 'row',
    alignItems: 'center',
    marginRight: 14,
  },
```

Hence, we will get the following result in our emulator screen:

![](https://kriss.io/wp-content/uploads/2019/10/Screenshot_1570359597.png)

As we can see, we have got the proper but incomplete list item in the emulator screen. Incomplete because we still need to add the Image to the left and a menu icon to the right. So, let us get on with adding the menu button to the right first.

### Adding Vertical Option Menu button

Here, we are going to add a menu button that has a vertical options icon. The icon we want to include is not available in the `FontAwesome` or `Ionicons` icon package. So, we need to import one more icon package that is  `SimpleLineIcons` icon package from vector icons package as shown in the code snippet below:

```javascript
import { FontAwesome , Ionicons, SimpleLineIcons} from '@expo/vector-icons';
```

Now, we are going to make use of `SimpleLineIcons` package to add a vertical option icon menu button at the right. In order to do that, we need to add one more `View` component inside the second child `View` component of the `renderList()` as shown in the code snippet below:

```javascript
<View style={styles.campingDetails}>
              <View style={{ flex: 1, flexDirection: 'column', justifyContent: 'center' }}>
                <Text style={{ fontSize: 14, fontWeight: 'bold' }}>
                  Camping title
                </Text>
                <Text style={{ fontSize: 12, color: '#A5A5A5', paddingTop: 5 }}>
                  Camping description
                </Text>
              </View>
              <View style={{ flex: 1, flexDirection: 'row', }}>
                <View style={styles.campingInfo}>
                  <FontAwesome name="star" color="#FFBA5A" size={12} />
                  <Text style={{ marginLeft: 4, color: '#FFBA5A' }}>3.5</Text>
                </View>
                <View style={styles.campingInfo}>
                  <FontAwesome name="location-arrow" color="#FF7657" size={12} />
                  <Text style={{ marginLeft: 4, color: '#FF7657' }}>3.0miles</Text>
                </View>
                <View style={styles.campingInfo}>
                  <Ionicons name="md-pricetag" color="black" size={12} />
                  <Text style={{ marginLeft: 4, color: 'black' }}>Free</Text>
                </View>
              </View>
            </View>

            <View style={{ flex: 0.2, justifyContent: 'center' }}>
              <SimpleLineIcons name="options-vertical" color="#A5A5A5" size={24} />
            </View>
</View>
```

Here, we have added the `View` component wrapping the `SimpleLineIcons` component which has the icon name` options-verticle` with some `color` and `size` props.

Hence, we get the following result in our emulator screen:

![](https://kriss.io/wp-content/uploads/2019/10/Screenshot_1570359828.png)

As we can see, we have got the options button on the right side of the list item. Now, we are going to replace the manual placeholder data with the mock data that we defined earlier in the `campings` array.


### Integrating Mock data

In this step, we are going to integrate accurate data to accurate placeholders in the list item template. Since we have an array with two objects, we are going to iterate through the array using `map()` array function available in react-native. The `map()` function allows us to iterate through each item in an array and return the required template. The parent `View` component inside the `map()` function will take on a unique id known as `key` which will identify each list item uniquely. Now, to implement the `map()` array function and iterate through the array which will return the template for each item with mock data, we need to use the code provided in the code snippet below into our `renderList()` method:

```javascript
return campings.map(
      camping => {
        return (
          <View key={`camping-${camping.id}`} style={styles.camping}>
            <View>
              <Image />
            </View>
            <View style={styles.campingDetails}>
              <View style={{ flex: 1, flexDirection: 'column', justifyContent: 'center' }}>
                <Text style={{ fontSize: 14, fontWeight: 'bold' }}>
                  {camping.name}
                </Text>
                <Text style={{ fontSize: 12, color: '#A5A5A5', paddingTop: 5 }}>
                  {camping.description}
                </Text>
              </View>
              <View style={{ flex: 1, flexDirection: 'row', }}>
                <View style={styles.campingInfo}>
                  <FontAwesome name="star" color="#FFBA5A" size={12} />
                  <Text style={{ marginLeft: 4, color: '#FFBA5A' }}>{camping.rating}</Text>
                </View>
                <View style={styles.campingInfo}>
                  <FontAwesome name="location-arrow" color="#FF7657" size={12} />
                  <Text style={{ marginLeft: 4, color: '#FF7657' }}>{camping.distance} miles</Text>
                </View>
                <View style={styles.campingInfo}>
                  <Ionicons name="md-pricetag" color="black" size={12} />
                  <Text style={{ marginLeft: 4, color: 'black' }}>{camping.price}</Text>
                </View>
              </View>
            </View>
            <View style={{ flex: 0.2, justifyContent: 'center' }}>
              <SimpleLineIcons name="options-vertical" color="#A5A5A5" size={24} />
            </View>
          </View>
        )
})
```

Therefore, we will get following result in our emulator screen:

![](https://kriss.io/wp-content/uploads/2019/10/Screenshot_1570360651.png)

As we can see, we have successfully implemented the list section containing two list items. The list items emphasize the camping spots around the map in an actual app. But, we still need to include the image of the camping spots. So now, let us work on including the image.

### Including Image in the List

In this step, we are going to work on an image that is to be included on the left side of the list item. We have already separated a child `View` component inside the parent `View` component of `renderList()` method in which we have defined an `Image` component. Now, we are going to provide the source and some style properties to that Image component as shown in the code snippet below:

```javascript
        <View key={`camping-${camping.id}`} style={styles.camping}>
            <View style={{flex : 1, overflow: 'hidden'}}>
              <Image
                style={styles.campingImage}
                source={{ uri: camping.image }}
              />
            </View>
```

The required style is provided in the code snippet below:

```javascript
campingImage: {
    width: width * 0.30,
    height: width * 0.25,
    borderRadius: 6,
  },
```

Hence, we will get the following result in our emulator simulation:

<!--[if lt IE 9]><script>document.createElement('video');</script><![endif]--><video id="video-465-1" width="640" height="1280" loop="1" autoplay="1" preload="metadata" controls="controls"><source type="video/webm" src="https://kriss.io/wp-content/uploads/2019/10/scrolling.webm?_=1"></source><a href="https://kriss.io/wp-content/uploads/2019/10/scrolling.webm">https://kriss.io/wp-content/uploads/2019/10/scrolling.webm</a></video>

As we can see in the simulation above, we have got the image on the left side and the scrolling event also works properly. But the image style does not exactly match the image style in the actual app. So, we are going to make some small changes to the `Image` component in order to make it exactly like that in actual Camping Spot Finder app.

### Changing Image component to **ImageBackground**

Here, we are going to replace the `Image` component with `ImageBackground` component.  The `ImageBackground` component is a synonym to the `background-image` property of CSS on the web. `<ImageBackground>` component has the same props as the `Image` component and enables us to add whatever children to it which we would like to layer on top of it. But first, we need to import the `ImageBackground` component from the react-native package as shown in the code snippet below:

```javascript
import {   ImageBackground,   Image,   Platform,   ScrollView,   StyleSheet,   Text,   TouchableOpacity,   View,   Dimensions,   SafeAreaView } from 'react-native';
```

Now, we need to add the `ImageBackground` component in place of `Image` component and use required props and styles as shown in the code snippet below:

![](https://kriss.io/wp-content/uploads/2019/10/Screenshot_1570361711.png)

Now, the image in the list section looks similar to that in the actual app. With this, we have successfully completed the implementation of the list section in our Camping Spot Finder App UI clone. The list with the information about the camping sites appears just like in the actual app.

Now, we are going to prepare a small pre-requisite for the next part of this tutorial series. That is to implement navigation to the settings screen.

## 

## Navigation to the Settings screen

This step is a small pre-requisite for our next part of this tutorial series. In this step, we are simply going to add navigation to the settings screen in the settings icon button we created in the header section. We have already set up the `TouchableOpacity` component to the settings button in the header section inside the `renderHeader()` function. Now, we are going to add a navigation control to navigate to the settings screen in the `onPress` event of the `TouchableOpacity` component as shown in the code snippet below:

```javascript
<View style={styles.settings}>
            <TouchableOpacity onPress={() => this.props.navigation.navigate('Settings')}>
              <Ionicons name="ios-settings" size={24} color="black" />
            </TouchableOpacity>
          </View>
```

Since our Campings screen is already set up in the navigator stack, the `navigation` instance that provides `navigate()` function is readily available to us in the `prop` variable. So, by using the `navigate()` function with parameter as ‘Settings’, we can navigate to Settings screen just by clicking on the settings button on the header section as shown in the emulator simulation below:

<video id="video-465-2" width="640" height="1280" loop="1" autoplay="1" preload="metadata" controls="controls"><source type="video/webm" src="https://kriss.io/wp-content/uploads/2019/10/settings-navigation.webm?_=2"></source><a href="https://kriss.io/wp-content/uploads/2019/10/settings-navigation.webm">https://kriss.io/wp-content/uploads/2019/10/settings-navigation.webm</a></video>

Finally, we have successfully implemented the list section as well as navigation to the Settings screen in our Camping Spot Finder App UI clone.

## 

## Conclusion

This tutorial is the second part of the Camping Spot Finder App UI clone tutorial series. In this part, we continued from where we left off in the first part of this tutorial series. In the part of the tutorial, we first learned how to make use of `SafeAreaView` component. Then, we learned how to integrate the mock data into the template using `map()` array function. We also learned about one new component that is `ImageBackground` component that we imported from react-native package to place the image properly on the list section. Lastly, we got an insight on how to use `navigate()` function provided by `navigation` instance available in `prop` variable to navigate to the Settings screen.

In the next part, we are going to implement the different components of the Settings screen in our Camping Spots Finder App UI clone.

_So, Stay Tuned folks!!_

The post [Camping Spots Finder App UI Clone with React Native #2 : List Section](https://kriss.io/camping-spots-finder-app-ui-clone-with-react-native-2-list-section/) appeared first on [Kriss](https://kriss.io).

## Disclosure
This post includes affiliate links; I may receive compensation if you purchase
products or services from different links provided in this article