React Native 네트워크 4

윤수환·2025년 3월 20일

React Native

목록 보기
25/26

패키지
npm install react-native-google-places-autocomplete

  • 장소 자동 완성 기능

변경점
Main_Map

import { JSX } from "react";
import { SafeAreaView, StyleSheet, Text, View, TextInput, TouchableOpacity } from "react-native";
import Icon from 'react-native-vector-icons/FontAwesome';
import { widthPercentageToDP as wp, heightPercentageToDP as hp } from "react-native-responsive-screen";
import { useState, useRef } from 'react';
import MapView, {PROVIDER_GOOGLE, Marker, Polyline} from "react-native-maps";
import { GooglePlacesAutocomplete } from "react-native-google-places-autocomplete";

function Main_Map() : JSX.Element {
    console.log("-- Main_Map()")

    const mapRef : any = useRef(null)

    const [initalRegion, setInitalRegion] = useState({
        latitude: 37.5666612,
        longitude: 126.9783785,
        latitudeDelta: 0.0922,
        longitudeDelta: 0.0421
    })

    const [showBtn, setShowBtn] = useState(false)

    const handleLongPress = async(event:any) => {
        setShowBtn(true)
    }

    const handleAddMarker = (title:string) => {
        setShowBtn(false)
    }

    let query = {
        key: "AIzaSyCxAEv4QYaJJxSTf46MC5BujoJcsavmjJw",
        language: "ko",
        components: "country:kr"
    }

    const [marker1, setMarker1] = useState({latitude:0, longitude:0})
    const [marker2, setMarker2] = useState({latitude:0, longitude:0})

    const onSelectAddr = (data:any, details:any, type:string) => {
        if (details) {
            let lat = details.geometry.location.lat
            let lng = details.geometry.location.lng

            if(type=="start") {
                setMarker1({latitude:lat, longitude:lng})
                if (marker2.longitude==0) {
                    setInitalRegion({
                        latitude:lat, longitude:lng,
                        latitudeDelta: 0.0073, longitudeDelta: 0.0064
                    })
                }
            }
            else {
                setMarker2({latitude:lat, longitude:lng})
                if (marker1.longitude==0) {
                    setInitalRegion({
                        latitude:lat, longitude:lng,
                        latitudeDelta: 0.0073, longitudeDelta: 0.0064
                    })
                }
            }
        }
    }

    if (marker1.latitude!=0 && marker2.latitude!=0) {
        if (mapRef.current) {
            mapRef.current.fitToCoordinates([marker1, marker2], {
                edgePadding: {top: 120, right: 50, bottom: 50, left: 50},
                animated:true
            })
        }
    }

    return (
        <SafeAreaView style={styles.container}>
            <MapView style={styles.container} provider={PROVIDER_GOOGLE}
            region={initalRegion} ref={mapRef}>
                <Marker coordinate={marker1} title="출발 위치"/>
                <Marker coordinate={marker2} title="도착 위치" pinColor="blue"/>
                {marker1.latitude !=0 && marker2.latitude !=0 && (
                    <Polyline
                    coordinates={[marker1, marker2]}
                    strokeColor="blue"
                    strokeWidth={3}/>
                )}
            </MapView>

            <View style={{position:'absolute', width:'100%', height:'100%', padding:10}}>
                <View style={{position:'absolute', padding:wp(2)}}>
                    <View style={{width:wp(75)}}>
                        <GooglePlacesAutocomplete
                            onPress={(data, details) => onSelectAddr(data, details, 'start')}
                            minLength={2}
                            placeholder="출발지 검색"
                            query={query}
                            keyboardShouldPersistTaps={"handled"}
                            fetchDetails={true}
                            enablePoweredByContainer={false}
                            onFail={(error) => console.log(error)}
                            onNotFound={() => console.log("no results")}
                            styles={autocompleteStyles}
                            />
                    </View>
                    <View style={{width:wp(75)}}>
                        <GooglePlacesAutocomplete
                            onPress={(data, details) => onSelectAddr(data, details, 'end')}
                            minLength={2}
                            placeholder="도착지 검색"
                            query={query}
                            keyboardShouldPersistTaps={"handled"}
                            fetchDetails={true}
                            enablePoweredByContainer={false}
                            onFail={(error) => console.log(error)}
                            onNotFound={() => console.log("no results")}
                            styles={autocompleteStyles}
                            />
                    </View>
                </View>
                <TouchableOpacity 
                style={[styles.button,
                    {position:'absolute', width: wp(18), top:wp(2), right:wp(2), height: 90, justifyContent:'center'}]}>
                    <Text style={styles.buttonText}>호출</Text>
                </TouchableOpacity>
            </View>

            <TouchableOpacity style={[{position:'absolute', bottom:20, right:20}]}>
                <Icon name="crosshairs" size={40} color={'#3498db'}/>
            </TouchableOpacity>

            <View style={{position:'absolute', top: hp(50)-45, left: wp(50)-75, height:90, width:150}}>
                <TouchableOpacity style={[styles.button, {flex:1, marginVertical:1}]}
                onPress={()=>handleAddMarker('출발지')}
                >
                    <Text style={styles.buttonText}>출발지로 등록</Text>
                </TouchableOpacity>
                <TouchableOpacity style={[styles.button, {flex:1}]}
                onPress={()=>handleAddMarker('출발지')}
                >
                    <Text style={styles.buttonText}>도착지로 등록</Text>
                </TouchableOpacity>
            </View>

        </SafeAreaView>
    )
}

const autocompleteStyles = StyleSheet.create ({
    textInputContainer: {
        width: '100%',
        backgroundColor:'#e9e9e9',
        borderRadius: 8,
        height: 40
    },
    textInput: {
        height: 40,
        color: '#5d5d5d',
        fontSize: 16
    },
    predefindPlacesDescription: {
        color: '#1faadb',
        zIndex: 1
    }
})

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        width: '100%'
    },
    button: {
        backgroundColor: '#3498db',
        paddingVertical: 10,
        paddingHorizontal: 20,
        borderRadius: 5
    },
    buttonDisable: {
        backgroundColor: 'gray',
        paddingVertical: 10,
        paddingHorizontal: 20,
        borderRadius: 5
    },
    buttonText: {
        color: 'white',
        fontSize: 16,
        textAlign: 'center'
    },
    input: {
        height: 40,
        borderWidth: 2,
        borderColor: 'gray',
        marginVertical: 1,
        padding: 10
    }
})

export default Main_Map

0개의 댓글