Home
Button Mobile Webdesign em Foco
Newsletter Webdesign em Foco
Support Webdesign em Foco
Contribuition Webdesign em Foco
Doe para a Webdesign em Foco
Suporte da Webdesign em Foco
Fechar

Mapas e Rotas com React Native - #8 Organização em Screens

28/02/2021

Nesse tutorial trabalharemos com as telas (screens) personalizadas do nosso app construido com React Native, organizando o projeto.

Screens no React Native

Vamos começar instalando o módulo React Navigation e suas dependências:

npm install @react-navigation/native
expo install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-masked-view/masked-view
npm install @react-navigation/stack
expo start --android

Na raiz do nosso projeto vamos criar um diretório views e dentro dela vamos criar os componentes do sistema.

views/Home.js

Receberá o template da página de abertura do nosso app.

import React, {useState,useEffect,useRef} from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
import {css} from '../assets/css/Css';
import MapView from 'react-native-maps';
import * as Location from 'expo-location';
import * as Permissions from 'expo-permissions';
import config from '../config';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
import MapViewDirections from 'react-native-maps-directions';
import { MaterialIcons } from '@expo/vector-icons';

export default function Home(props) {

    const mapEl=useRef(null);
    const [origin,setOrigin]=useState(null);
    const [destination,setDestination]=useState(null);
    const [distance,setDistance]=useState(null);
    const [price,setPrice]=useState(null);


    useEffect(()=>{
        (async function(){
            const { status, permissions } = await Permissions.askAsync(Permissions.LOCATION);
            if (status === 'granted') {
                let location = await Location.getCurrentPositionAsync({enableHighAccuracy: true});
                setOrigin({
                    latitude: location.coords.latitude,
                    longitude: location.coords.longitude,
                    latitudeDelta: 0.000922,
                    longitudeDelta: 0.000421
                })
            } else {
                throw new Error('Location permission not granted');
            }
        })();
    },[]);


    return (
        <View style={css.container}>
            <MapView
                    style={css.map}
                    initialRegion={origin}
                    showsUserLocation={true}
                    zoomEnabled={false}
                    loadingEnabled={true}
                    ref={mapEl}
            >
                {destination &&
                <MapViewDirections
                        origin={origin}
                        destination={destination}
                        apikey={config.googleApi}
                        strokeWidth={3}
                        onReady={result=>{
                        setDistance(result.distance);
                        setPrice(result.distance*3);
                        mapEl.current.fitToCoordinates(
                            result.coordinates,{
                                edgePadding:{
                                    top:50,
                                    bottom:50,
                                    left:50,
                                    right:50
                                }
                            }
                        );
                    }
                    }
                />
                }

            </MapView>

            <View style={css.search}>
                <GooglePlacesAutocomplete
                        placeholder='Para onde vamos?'
                        onPress={(data, details = null) => {
                        setDestination({
                            latitude: details.geometry.location.lat,
                            longitude: details.geometry.location.lng,
                            latitudeDelta: 0.000922,
                            longitudeDelta: 0.000421
                        });
                    }}
                    query={{
                        key: config.googleApi,
                        language: 'pt-br',
                    }}
                    enablePoweredByContainer={false}
                    fetchDetails={true}
                    styles={{
                        listView:{backgroundColor:'#fff', zIndex:10},
                        container:{position:'absolute',width:'100%'}
                    }}
                />

                {distance &&
                <View style={css.distance}>
                    <Text style={css.distance__text}>Distância: {distance.toFixed(2).replace('.',',')}km</Text>
                    <TouchableOpacity style={css.price} onPress={() => props.navigation.navigate('Checkout',{price: price.toFixed(2)})}>
                        <Text style={css.price__text}><MaterialIcons name="payment" size={24} color="white" /> Pagar R${price.toFixed(2).replace('.',',')}</Text>
                    </TouchableOpacity>
                </View>
                }
            </View>
        </View>
    );
}

App.js

Nosso entry point ficará mais limpo da seguinte maneira:

import React, {useState,useEffect,useRef} from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import {Home, Checkout} from './views';

const Stack = createStackNavigator();

export default function App() {
    return (
        <NavigationContainer>
            <Stack.Navigator>
                <Stack.Screen name="Home" component={Home} options={{headerShown:false}} />
                <Stack.Screen name="Checkout" component={Checkout} options={{headerShown:false}} />
            </Stack.Navigator>
        </NavigationContainer>
    );
}

views/index.js

Vamos criar o arquivo index para fazer as importações automáticas dos componentes do diretório views:

import Home from './Home';
import Checkout from './Checkout';

export {Home, Checkout};

views/Checkout.js

Vamos criar também a screen checkout que ficará responsável por receber os dados de pagamento futuramente:

import React, {useState,useEffect,useRef} from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
import {css} from '../assets/css/Css';

export default function Checkout(props) {

    return (
        <View style={css.container}>
            <Text>O valor da corrida é {props.route.params.price}</Text>
        </View>
    );
}

Por hoje é só turma. Sucesso nos códigos e na vida!

Precisando de assessoria? webdesignemfoco@gmail.com

Receba as aulas da Webdesign em Foco em Seu Email
Suporte Webdesign em Foco

Posts Relacionados

Mapas e Rotas com React Native - #7 Preço da Viagem
Nesse tutorial faremos a precificação da corrida, calculando a distância do usuário até o destino da viagem.
Saiba mais!
Mapas e Rotas com React Native - #9 Backend
Hoje iniciamos o a trabalhar com o lado servidor, ou seja, com o backend do nosso sistema que fará a interligação das nossas requisições do frontend.
Saiba mais!
React JS
Nessa seção aprenderemos sobre essa importante biblioteca Javascript desenvolvida pelo Facebook para facilitar a construção backend dos nossos websites.
Saiba mais!