Build a React Native App using Expo - Custom marker icons and Vector icons Part 2

05/07/2020   by Luciana Sato

In this post, you’ll be able to add custom markers on the google maps and how to add icons on the navigation tabs in your mobile application.

The video below shows how to implment this tutorial.

The result of this post, your application will be like the image below.

React Native App

This post is the second part of the tutorial how to build a React Native App using Expo

First, you need to choose the icon that you want to replace for the default marker and resize the icon. The size of the icons that will be used in this app is 32px (height and width) and I’m going to use 5 different icons.

After, add the icon(s) in the assets folder.

The response will be mock because there isn’t the api yet. The response has seven locations as you can see below and the map function is used to add all the locations on the map. The response is configured to add title, description, coordinates and the custom icon.

    import React from 'react'
    import MapView from 'react-native-maps'
    import { StyleSheet, Dimensions, Image } from 'react-native'
    
    const height = Dimensions.get('window').height
    
    const response = [
      {
        id: '1',
        coordinates: {
          latitude: -15.59611,
          longitude: -56.09667,
        },
        title: 'Cuiabá',
        description: 'Cuiabá',
        icon: require('../../assets/center.png')
      },
      {
        id: '2',
        coordinates: {
          latitude: -20.44278,
          longitude: -54.64639,
        },
        title: 'Campo Grande',
        description: 'Campo Grande',
        category: 1,
        icon: require('../../assets/center.png')
      },
      {
        id: '3',
        coordinates: {
          latitude: -23.5489,
          longitude: -46.6388,
        },
        title: 'São Paulo',
        description: 'São Paulo',
        category: 1,
        icon: require('../../assets/southeast.png')
      },
      {
        id: '4',
        coordinates: {
          latitude: -22.9035,
          longitude: -43.2096,
        },
        title: 'Rio de Janeiro',
        description: 'Rio de Janeiro',
        category: 1,
        icon: require('../../assets/southeast.png')
      },
      {
        id: '5',
        coordinates: {
          latitude: -3.71839,
          longitude: -38.5434,
        },
        title: 'Ceará',
        description: 'Ceará',
        category: 1,
        icon: require('../../assets/northeast.png')
      },
      {
        id: '6',
        coordinates: {
          latitude: -30.0277,
          longitude: -51.2287,
        },
        title: 'Rio Grande do Sul',
        description: 'Rio Grande do Sul',
        category: 1,
        icon: require('../../assets/south.png')
      },
      {
        id: '7',
        coordinates: {
          latitude: -9.974,
          longitude: -67.8076,
        },
        title: 'Acre',
        description: 'Acred',
        category: 1,
        icon: require('../../assets/north.png')
      }
    ]
    
    const Map = () => {
      return (
        <MapView
          style={styles.map}
          loadingEnabled={true}
          region={{
            latitude: -15.59611,
            longitude: -56.09667,
            latitudeDelta: 70,
            longitudeDelta: 1
          }}
        >
          {response.map(marker => (
            <MapView.Marker
              key={marker.id}
              coordinate={marker.coordinates}
              title={marker.title}
              description={marker.description}
            >
              <Image source={ marker.icon } style={{ height: 32, width: 32 }} />
            </MapView.Marker>
          ))}
        </MapView>
      )
    }
    
    const styles = StyleSheet.create({
      map: {
        height
      }
    })
    
    export default Map

After adding the locations and the custom icons, the next step is add the custom icon on the navigation tabs. For this, you need to install the package “react-native-vector-icons”.

expo install react-native-vector-icons

In the App.js file, add the configuration to change the color of the icons and hide the label.


    import React from 'react';
    import { StyleSheet, Text, View } from 'react-native';
    import { createAppContainer, createSwitchNavigator } from 'react-navigation'
    import { createBottomTabNavigator } from 'react-navigation-tabs'
    import MapScreen from './src/screens/MapScreen'
    import MapListScreen from './src/screens/MapListScreen'
    import { setNavigator } from './src/navigationRef'

    const switchNavigator = createSwitchNavigator({
      mainFlow: createBottomTabNavigator({
        MapView: MapScreen,
        MapList: MapListScreen
      }, {
        tabBarOptions: {
          showLabel: false,
          activeTintColor: '#3D8836'
        }
      })
    })

    const App = createAppContainer(switchNavigator)

    export default () => {
      return (
        <App 
          ref={navigator => {
            setNavigator(navigator)
          }}
        />
      );
    }

In the MapScreen and MapListScreen, add the navigation options. You can choose the icon, the size and the name of the label.


    import React from 'react'
    import { SafeAreaView } from 'react-navigation'
    import Map from '../components/Map'
    import Icon from 'react-native-vector-icons/Ionicons'

    const MapScreen = ({ navigation }) => {
      return (
        <SafeAreaView forceInset={{ top: 'always' }}>
          <Map />
        </SafeAreaView>
      )
    }

    MapScreen.navigationOptions = {
      tabBarIcon: ({ tintColor }) => (
        <Icon name="md-map" color={ tintColor } size={ 30 } />
      )
    }

    export default MapScreen


    import React from 'react'
    import { SafeAreaView } from 'react-navigation'
    import { Text, StyleSheet } from 'react-native'
    import Icon from 'react-native-vector-icons/Ionicons'

    const MapListScreen = ({ navigation }) => {
      return (
        <SafeAreaView forceInset={{ top: 'always' }}>
          <Text style={{ fontSize: 50 }}>MapListScreen</Text>
        </SafeAreaView>
      )
    }

    MapListScreen.navigationOptions = {
      tabBarIcon: ({ tintColor }) => (
        <Icon name="ios-list" color={ tintColor } size={ 30 } />
      )
    }

    export default MapListScreen


In the next tutorial, you can see how to implement the list screen.

See you