如何在React Native中从Google地图自动完成获取地址

时间:2018-07-18 04:32:57

标签: google-maps react-native autocomplete react-native-maps react-props

我正在使用 react-native-google-places-autocomplete 选择位置。我要提取选定的位置,并在其他组件中使用它。

如何保存地址

这是我的代码

import React, {Component} from 'react';
import { View, Image, Text, StyleSheet } from 'react-native';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';

const homePlace = { description: 'Home', geometry: { location: { lat: 48.8152937, lng: 2.4597668 } }};
const workPlace = { description: 'Work', geometry: { location: { lat: 48.8496818, lng: 2.2940881 } }};

export default class google extends Component {
  render(){

  return (
    <View style={styles.container}>
      <View style={styles.top}>
    <GooglePlacesAutocomplete
      placeholder='Search'
      minLength={2} // minimum length of text to search
      autoFocus={false}
      returnKeyType={'search'} // Can be left out for default return key https://facebook.github.io/react-native/docs/textinput.html#returnkeytype
      listViewDisplayed='auto'    // true/false/undefined
      fetchDetails={true}
      renderDescription={row => row.description} // custom description render
      onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
        console.log(data, details);
        this.setState(
                  {
                    address: data.description, // selected address
                    coordinates: `${details.geometry.location.lat},${details.geometry.location.lng}` // selected coordinates
                  }
                );
      }}

      getDefaultValue={() => ''}

      query={{
        // available options: https://developers.google.com/places/web-service/autocomplete
        key: 'AIzaS#################',
        language: 'es', // language of the results

      }}

      styles={{
        textInputContainer: {
          width: '100%'
        },
        description: {
          fontWeight: 'bold'
        },
        predefinedPlacesDescription: {
          color: '#1faadb'
        }
      }}

      currentLocation={true} // Will add a 'Current location' button at the top of the predefined places list
      currentLocationLabel="Current location"
      nearbyPlacesAPI='GooglePlacesSearch' // Which API to use: GoogleReverseGeocoding or GooglePlacesSearch
      GoogleReverseGeocodingQuery={{
        // available options for GoogleReverseGeocoding API : https://developers.google.com/maps/documentation/geocoding/intro
      }}
      GooglePlacesSearchQuery={{
        // available options for GooglePlacesSearch API : https://developers.google.com/places/web-service/search
        rankby: 'distance',
        types: 'food'
      }}

      filterReverseGeocodingByTypes={['locality', 'administrative_area_level_3']} // filter the reverse geocoding results by types - ['locality', 'administrative_area_level_3'] if you want to display only cities
      predefinedPlaces={[homePlace, workPlace]}

      debounce={200} // debounce the requests in ms. Set to 0 to remove debounce. By default 0ms.
      renderRightButton={() => <Text>Custom text after the input</Text>}
    />
    </View>
    <View style={styles.container2}>
      <Text>
        hola {this.setState.address}
      </Text>
    </View>
    </View>

  );
}
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  width: '100%',
height: '100%',

  },
  welcome: {
    fontSize: 40,
    textAlign: 'center',
    margin: 10,
color:'black',
  },
  instructions: {
    textAlign: 'center',
    color: 'black',
    marginBottom: 5,
  },
top: {
height: '50%',
justifyContent: 'center',
    alignItems: 'center',
  },

container2: {
   height:'75%',
   justifyContent: 'center',
  },
buttonContainer: {
alignItems: 'center',
    backgroundColor: 'rgba(255, 255,255, 0.5)',
    padding: 1,
    margin: 50,
    borderRadius: 25,
    borderWidth: 2,
    borderColor: '#0B0B3B'

     },
textoboton: {
    textAlign: 'center',
    color: 'black',
    marginBottom: 5,
    fontSize: 12

  },

})

我也一直在使用另一个具有某些区别的库

app.js

import React,{Component} from 'react';
import { Constants } from 'expo';
import Icon from 'react-native-vector-icons/FontAwesome';
import { View, Image, Text, StyleSheet, AsyncStorage, Button,ScrollView, TextInput, ActivityIndicator } from 'react-native';
import {
  NavigationActions
} from 'react-navigation';
import { GoogleAutoComplete } from 'react-native-google-autocomplete';
import {Card, Input} from "react-native-elements";

import LocationItem from './locationItem';


export default class App extends React.Component {

  state={
    datos:[],
  }
  componentDidMount(){
    this._loadedinitialstate().done();
  }
  _loadedinitialstate =async() => {
    AsyncStorage.getItem('datos');
  }

  render() {
    return (
      <View style={styles.container}>
        <GoogleAutoComplete apiKey={'AIzaSyB2HyNTBm1sQJYJkwOOUA1LXRHAKh4gmjU'} debounce={20} minLength={2} getDefaultValue={() => ''}  onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
        console.log(data, details);}}   returnKeyType={'default'} fetchDetails={true}
>
          {({
            locationResults,
            isSearching,
            clearSearchs,
            datos,
            handleTextChange
          }) => (
            <React.Fragment>
              <View style={styles.inputWrapper}>
                <Input
                  style={styles.textInput}
                  placeholder="Ingresa tu direccion"
                  onChangeText={(datos) => this.setState({datos})}
                  value={datos}
                />

              </View>
              {isSearching && <ActivityIndicator size="large" color="red" />}
             <ScrollView>
               {locationResults.map(el => (
                 <LocationItem
                   {...el}
                   key={el.id}
                 />
               ))}
             </ScrollView>
            </React.Fragment>
          )}
        </GoogleAutoComplete>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  textInput: {
    height: 40,
    width: 300,
    borderWidth: 1,
    paddingHorizontal: 16,
  },
  inputWrapper: {
    marginTop: 80,
    flexDirection: 'row'
  },
});

locationitem.js

import React, { PureComponent } from 'react';
import { View, Alert, Text, StyleSheet, TouchableOpacity, AsyncStorage} from 'react-native';

class LocationItem extends PureComponent {

  constructor(props) {
    super(props);
    this.state = {datos:''};
  }

  _handlePress = () => {
    AsyncStorage.setItem('datos',datos)
  }



  render() {
    return (
      <TouchableOpacity style={styles.root} onPress={this._handlePress}  >
        <Text value={this.state.datos}> {this.props.description} </Text>
      </TouchableOpacity>
    );
  }
}

const styles = StyleSheet.create({
  root: {
    height: 40,
    borderBottomWidth: StyleSheet.hairlineWidth,
    justifyContent: 'center'
  }
})

export default LocationItem;

这两个代码的来源在这里react-native-google-places-autocomplete enter link description here

哪些代码将易于使用,以及如何解决我的问题(获取地址)?

任何答案都会有帮助

4 个答案:

答案 0 :(得分:2)

经过漫长的旅程,这些步骤帮助我解决了问题。

1)安装npm install react-native-google-places-autocomplete --save

2)然后使用下面的代码作为组件中的元素。

<GooglePlacesAutocomplete
          query={{
            key: "GOOGLE_PLACES_API_KEY",
            language: "en", // language of the results
          }}
          onPress={(data, details = null) => {
            console.log(details);
            console.log(data);
            console.log("data.description",data.description.split(','));

          }}
          onFail={(error) => console.error(error)}
          listViewDisplayed="false"
          requestUrl={{
            url:
              "https://cors-                  
         anywhere.herokuapp.com/https://maps.googleapis.com/maps/api",
            useOnPlatform: "web",
          }} // this in only required for use on the web. See https://git.io/JflFv 
            more for details.
          styles={{
            textInputContainer: {
              backgroundColor: "rgba(0,0,0,0)",
              borderTopWidth: 0,
              borderBottomWidth: 0,
            },
            textInput: {
              marginLeft: 0,
              marginRight: 0,
              height: 38,
              color: "#5d5d5d",
              fontSize: 16,
            },
            predefinedPlacesDescription: {
              color: "#1faadb",
            },
          }}
        />

3)您可能遇到与我相同的问题,当我尝试选择结果时,列表会消失。但是,这是为我解决了这个问题的措施。 在node_modules上注释onBlur。路径:“ .. \ node_modules \ react-native-google-places-autocomplete \ GooglePlacesAutocomplete.js”。

    ...
    onFocus={onFocus ? () => {this._onFocus(); onFocus()} : this._onFocus}
    // onBlur={this._onBlur}
    underlineColorAndroid={this.props.underlineColorAndroid}
    ... 

4)为了保存地址,您可以在代码中检查console.log,然后使用setState或类似的东西。

5)有关这些元素的更多信息和选项,请查看此存储库: https://github.com/FaridSafi/react-native-google-places-autocomplete

希望这对您有帮助:)

答案 1 :(得分:1)

首次安装

npm i react-native-google-places-autocomplete

然后

import React from 'react';
import { View, Image } from 'react-native';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';

const homePlace = { description: 'Home', geometry: { location: { lat: 48.8152937, lng: 2.4597668 } }};
const workPlace = { description: 'Work', geometry: { location: { lat: 48.8496818, lng: 2.2940881 } }};

const GooglePlacesInput = () => {
  return (
    <GooglePlacesAutocomplete
      placeholder='Search'
      minLength={2} // minimum length of text to search
      autoFocus={false}
      returnKeyType={'search'} // Can be left out for default return key https://facebook.github.io/react-native/docs/textinput.html#returnkeytype
      listViewDisplayed='auto'    // true/false/undefined
      fetchDetails={true}
      renderDescription={row => row.description} // custom description render
      onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
        console.log(data, details);
      }}

      getDefaultValue={() => ''}

      query={{
        // available options: https://developers.google.com/places/web-service/autocomplete
        key: 'YOUR API KEY',
        language: 'en', // language of the results
        types: '(cities)' // default: 'geocode'
      }}

      styles={{
        textInputContainer: {
          width: '100%'
        },
        description: {
          fontWeight: 'bold'
        },
        predefinedPlacesDescription: {
          color: '#1faadb'
        }
      }}

      currentLocation={true} // Will add a 'Current location' button at the top of the predefined places list
      currentLocationLabel="Current location"
      nearbyPlacesAPI='GooglePlacesSearch' // Which API to use: GoogleReverseGeocoding or GooglePlacesSearch
      GoogleReverseGeocodingQuery={{
        // available options for GoogleReverseGeocoding API : https://developers.google.com/maps/documentation/geocoding/intro
      }}
      GooglePlacesSearchQuery={{
        // available options for GooglePlacesSearch API : https://developers.google.com/places/web-service/search
        rankby: 'distance',
        types: 'food'
      }}

      filterReverseGeocodingByTypes={['locality', 'administrative_area_level_3']} // filter the reverse geocoding results by types - ['locality', 'administrative_area_level_3'] if you want to display only cities
      predefinedPlaces={[homePlace, workPlace]}

      debounce={200} // debounce the requests in ms. Set to 0 to remove debounce. By default 0ms.
      renderLeftButton={()  => <Image source={require('path/custom/left-icon')} />}
      renderRightButton={() => <Text>Custom text after the input</Text>}
    />
  );
}

答案 2 :(得分:1)

首先,我使用了 listViewDisplayed = {false} ,因为否则列表视图会卡在结果中,甚至在位置按下时,列表也不会关闭。

第二,回答您的问题:结果在GooglePlacesAutocomplete的 onPress 功能中,您可以使用所选位置更新状态,然后在组件中的任何位置使用它:

onPress={(data, details = null) => {
          this.setState({
          latitude: details.geometry.location.lat,
          longitude: details.geometry.location.lng,
          moveToUserLocation: true
        });
          this._gotoLocation();
        }
      }

如我所写,onPress还触发了移动地图以显示新位置的功能。

答案 3 :(得分:0)

import React, {Component} from 'react';
import { View, Image, Text, StyleSheet } from 'react-native';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';


export default class google extends Component {
        constructor(props) {
                super(props);
                this.state = {
                    address:null,
                    lat:null,
                    lng:null,
                }
            }

     getAdd(data){
        console.log("add",data);
        this.setState(
            {
              address: data.formatted_address, // selected address
              lat: data.geometry.location.lat,//  selected coordinates latitude
              lng:data.geometry.location.lng, //  selected coordinates longitute

            }
          );
       console.log("this.state.address",this.state.address); ///to console address
       console.log("this.state.coordinates",this.state.lat,this.state.lng); /// to console coordinates

    }


  render(){

  return (
    <View style={styles.container}>
      <View style={styles.top}>
        <GooglePlacesAutocomplete
            placeholder='Search'
            minLength={2} // minimum length of text to search
            autoFocus={false}
            fetchDetails={true}
            returnKeyType={'default'}
            onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true

              var data = details;
              this.getAdd(data);
            }}
            query={{
              // available options: https://developers.google.com/places/web-service/autocomplete
              key: 'AIzaS#################',
              language: 'en',
              types: 'geocode', // default: 'geocode'
            }}

            listViewDisplayed={this.state.showPlacesList}
            textInputProps={{
              onFocus: () => this.setState({ showPlacesList: true }),
              onBlur: () => this.setState({ showPlacesList: false }),
            }}
            styles={{
                textInputContainer: {
                  width: '100%'
                },
                description: {
                  fontWeight: 'bold'
                },
                predefinedPlacesDescription: {
                  color: '#1faadb'
                }
              }}

            currentLocation={true} // Will add a 'Current location' button at the top of the predefined places list
            currentLocationLabel="Current location"
            nearbyPlacesAPI='GooglePlacesSearch' // Which API to use: GoogleReverseGeocoding or GooglePlacesSearch

            filterReverseGeocodingByTypes={['locality', 'administrative_area_level_3']} // filter the reverse geocoding results by types - ['locality', 'administrative_area_level_3'] if you want to display only cities
            // predefinedPlaces={[]}

            predefinedPlacesAlwaysVisible={true}
          />

            </View>

            { this.state.address !=null ?(
            <View style={styles.container2}>
            <Text>
                Address: {this.state.address}
            </Text>
            </View>
            ):null }
            </View>

  );
}
}

const styles = StyleSheet.create({
  container: {
  width: '100%',
height: '100%',

  },
  welcome: {
    fontSize: 40,
    textAlign: 'center',
    margin: 10,
color:'black',
  },
  instructions: {
    textAlign: 'center',
    color: 'black',
    marginBottom: 5,
  },
top: {
height: '50%',
justifyContent: 'center',
    alignItems: 'center',
  },

container2: {
   height:'75%',
   justifyContent: 'center',
  },
buttonContainer: {
alignItems: 'center',
    backgroundColor: 'rgba(255, 255,255, 0.5)',
    padding: 1,
    margin: 50,
    borderRadius: 25,
    borderWidth: 2,
    borderColor: '#0B0B3B'

     },
textoboton: {
    textAlign: 'center',
    color: 'black',
    marginBottom: 5,
    fontSize: 12

  },

})