react-native:setState()不使用react-native-geolocation-service更新MapView initialRegion

时间:2019-12-05 10:17:03

标签: javascript android react-native geolocation

在我的本机应用程序中,我react-native-geolocation-service正在获取用户位置并将其显示在MapView上。以下是我尝试从网上提供的各种示例中尝试的简单代码。

import React, { Component } from 'react'
import 
{
    View,
    StyleSheet,
    Dimensions
} from 'react-native'
import MapView, { PROVIDER_GOOGLE, Marker } from 'react-native-maps';

//import Geolocation from '@react-native-community/geolocation';
import Geolocation from 'react-native-geolocation-service';
import {hasLocationPermission} from '../../../services/Helper'

const {width, height} = Dimensions.get('window')

const SCREEN_HEIGHT = height
const SCREEN_WIDTH = width
const ASPECT_RATIO = width / height
const LATITUDE_DELTA = 0.0922
const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO
const MAP_LOCATION_OPTIONS = { enableHighAccuracy: true, timeout: 20000};

class NearMeTest extends Component {

    constructor(){
        super()
        this.state = {
            initialPosition: {
                latitude: 0,
                longitude: 0,
                latitudeDelta: 0,
                longitudeDelta: 0,
            },
            markers: [{
                title: 'shop1',
                coordinates: {
                  latitude: 12.9782933,
                  longitude: 77.68838
                },
              },
              {
                title: 'shop2',
                coordinates: {
                  latitude: 12.9613824,
                  longitude: 77.7109504
                },
              },
            ]
        }
        this.onCurrentLocationSuccess = this.onCurrentLocationSuccess.bind(this)
        this.onCurrentLocationError = this.onCurrentLocationError.bind(this)
    }

    onCurrentLocationSuccess(pos) {

      var crd = pos.coords;
      var lat = parseFloat(crd.latitude)
      var long = parseFloat(crd.longitude)
      console.log('Your current position is:');
      console.log(`Latitude : ${lat}`);
      console.log(`Longitude: ${long}`);
      console.log(`More or less ${crd.accuracy} meters.`);
      var initialRegion = {
        latitude: lat,
        longitude: long,
        latitudeDelta: LATITUDE_DELTA,
        longitudeDelta: LONGITUDE_DELTA,
      }
      this.setState({initialPosition: initialRegion})
      };

    onCurrentLocationError(err) {
      console.warn(`ERROR(${err.code}): ${err.message}`);
      alert(err.message)
    };

    componentDidMount(){
      if(hasLocationPermission()){
        console.log('Location Permission present, getting current location')
        Geolocation.getCurrentPosition(this.onCurrentLocationSuccess,this.onCurrentLocationError,MAP_LOCATION_OPTIONS)
      }
    }


    render() {
        console.log(this.state.initialPosition)
        return (
            <View style={styles.container}>
                <MapView
                provider={PROVIDER_GOOGLE} // remove if not using Google Maps
                style={styles.map}
                initialRegion={this.state.initialPosition}
                >
                    <Marker
                        coordinate = {{
                            latitude: this.state.initialPosition.latitude,
                            longitude: this.state.initialPosition.longitude, 
                        }}
                    >
                    </Marker>
                    {this.state.markers.map((marker, i) => (
                    <Marker
                        key={i}
                        coordinate={marker.coordinates}
                        title={marker.title}
                    >
                    </Marker>
                    ))}
                </MapView>
            </View>
        )
    }
}

const styles = StyleSheet.create({
    container: {
      ...StyleSheet.absoluteFillObject,
      height: SCREEN_HEIGHT,
      width: SCREEN_WIDTH,
      justifyContent: 'flex-end',
      alignItems: 'center',
    },
    map: {
      ...StyleSheet.absoluteFillObject,
    },
   });

export default NearMeTest

我在componentDidMount()中获得了位置,但是当我打电话给setState()来设置我的initialPosition时,我看不到它在MapView中更新。

另外,还有一件有趣的事情是,如果我使用@react-native-community/geolocation中的Geocoder,那么它将按预期工作。

我具有位置信息权限,并且正在使用Android Marshmellow设备进行测试。

2 个答案:

答案 0 :(得分:0)

如果唯一的目的是在地图上显示用户的位置,我将在下面推荐:

<MapView
  style={styles.map}
  region={this.state.region}
  onRegionChangeComplete={this.onRegionChange}
  onUserLocationChange={this.onUserLocationChange}
  showsUserLocation={true}>

如果您在showUserLocation={true}上遇到任何麻烦,请参阅此https://github.com/react-native-community/react-native-maps/issues/2747#issuecomment-475662120

链接中的线程仅建议请求对地图准备就绪的权限。以下是上面链接的摘录。

<Map
  onMapReady={() => {
     PermissionsAndroid.request(
     PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION
  ).then(granted => {
     alert(granted) // just to ensure that permissions were granted
 });
}}/>

答案 1 :(得分:-1)

您看不到更新,因为您正在更新 initialPosition 。如果将 initialRegion 设置为 region 道具,它将起作用。