admin管理员组

文章数量:1323730

I'm using MapView from 'react-native-maps'

I can't get the "showsMyLocationButton" to show, so I'm implementing my own.

I want do this without using React Native's geolocation because I find it to be slower than react-native-maps prop showsUserLocation. I use onUserLocationChange event which returns the coordinates. However when firing the onUserLocationChange event and setting a state which contains the userLocation, it automatically updates the region without me explicitly asking for it.

This is my code:

display_my_location(coordinate){
  alert("region changed")
  this.setState({
    region: {
      latitude: coordinate.latitude,
      longitude: coordinate.longitude,
      latitudeDelta: 0.004,
      longitudeDelta: 0.004
    },
  });
}

setUserLocation(coordinate){
  //alert("User location changed MAP SHOULDNT MOVE")
  this.setState({
    userLocation: {
      latitude: coordinate.latitude,
      longitude: coordinate.longitude,
      latitudeDelta: 0.004,
      longitudeDelta: 0.004
    }
  })
}

<MapView
      style={styles.map}
      showsMyLocationButton={true}
      onUserLocationChange={locationChangedResult => this.setUserLocation(locationChangedResult.nativeEvent.coordinate)}
      initialRegion={this.state.region_amon}
      showsUserLocation={true}
      region={this.state.region}
      mapType={this.state.map_style}
      showsCompass = {true}
      showsMyLocationButton={true}
      chacheEnabled={false}
      zoomEnabled={true}

I'm using MapView from 'react-native-maps'

I can't get the "showsMyLocationButton" to show, so I'm implementing my own.

I want do this without using React Native's geolocation because I find it to be slower than react-native-maps prop showsUserLocation. I use onUserLocationChange event which returns the coordinates. However when firing the onUserLocationChange event and setting a state which contains the userLocation, it automatically updates the region without me explicitly asking for it.

This is my code:

display_my_location(coordinate){
  alert("region changed")
  this.setState({
    region: {
      latitude: coordinate.latitude,
      longitude: coordinate.longitude,
      latitudeDelta: 0.004,
      longitudeDelta: 0.004
    },
  });
}

setUserLocation(coordinate){
  //alert("User location changed MAP SHOULDNT MOVE")
  this.setState({
    userLocation: {
      latitude: coordinate.latitude,
      longitude: coordinate.longitude,
      latitudeDelta: 0.004,
      longitudeDelta: 0.004
    }
  })
}

<MapView
      style={styles.map}
      showsMyLocationButton={true}
      onUserLocationChange={locationChangedResult => this.setUserLocation(locationChangedResult.nativeEvent.coordinate)}
      initialRegion={this.state.region_amon}
      showsUserLocation={true}
      region={this.state.region}
      mapType={this.state.map_style}
      showsCompass = {true}
      showsMyLocationButton={true}
      chacheEnabled={false}
      zoomEnabled={true}
Share Improve this question edited Aug 23, 2018 at 2:21 Jason Aller 3,65228 gold badges41 silver badges39 bronze badges asked Aug 22, 2018 at 22:34 Esteban G DamazioEsteban G Damazio 611 silver badge3 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 2

I believe you can fix this by deleting the region prop from the MapView altogether. If you need to have the map's bounding box change programmatically you can attach a ref to the map and update in ponentDidUpdate using the appropriate MapView method here:

https://github./react-munity/react-native-maps/blob/master/docs/mapview.md#methods

I have a workaround for the above issue, we can have a custom icon on the map. After clicking on the custom icon trigger a method. In the method get the current location coordinates using Geolocation and fire animateToRegion and pass the coordinates.

Step 1: Declare mapRef

const mapRef = useRef(null);

Step 2: Assing mapRef to MapView

<View style={{flex: 1}>
<MapView
       ref={mapRef}
       ...........
 />
<TouchableOpacity
  onPress={currentLocationHandler}>
  <MaterialIcons
    name="my-location"
    size={24}
    color="black"
  />
</TouchableOpacity>
</View>

Step 3: currentLocationHandler method

const currentLocationHandler = () => {
<!-- Get location coordinates using GeoLocation npm package -->
    let currentRegion = {
      latitude: latitude from geolocation,
      longitude: longitude from geolocation,
      latitudeDelta: 0.001,
      longitudeDelta: 0.001,
    };
    mapRef.current.animateToRegion(currentRegion, 3 * 1000);
}

I hope the above steps help you to solve the issue

The question explicitly states that GeoLocation module not to be used. I have the following answer which does not use GeoLocation but just MapView.

Step 1

You need to keep mutable references to map and user's location as follows:

// we need this to manipulate the map object
const mapRef = useRef<MapView>(null);

// this variable keeps current location of the user. Once the location changes the map
// updates it using a call back
const userCurrentLocation = useRef<LatLng>();

Step 2

In your render function render the map. I have a separate call to render the map and possibly markers as follows:

// This function renders the map and the children markers
const renderMap = ({ children }: MarkersProps, region: Region) => {
    return (
        <MapView
            initialRegion={region}
            ref={mapRef}
            style={styles.map}
            provider={PROVIDER_GOOGLE}
            showsUserLocation={true}
            showsMyLocationButton={false}
            showsScale={true}
            zoomTapEnabled={true}
            maxZoomLevel={17}
            minZoomLevel={12}
            onMapReady={onMapReady}
            onRegionChangeComplete={onRegionChangeComplete}
            onLayout={(event) => onLayout(event)}
            onUserLocationChange={(event) => { userCurrentLocation.current = event.nativeEvent.coordinate }}>
            {children}
        </MapView>
    );
};

Note that userCurrentLocation reference is updated when user location changes. This would be continously updated by the MapView if user moves all the time. I believe that you must have showsUserLocation set to true for this to work.

Step 3

Place a button/icon/element for user to press to pan to where the current user location is. How you design that is irrelevant to this solution. All you need to do is to place a call back for onPress event as follows:

<CurrentPositionButton getToCurrentPosition={function (): void {
    if (!userCurrentLocation.current)
        return;
    // set the bounds center to where the user location is and use Redux geoState distance
    // to find the region to pan to
    mapRef.current?.animateToRegion (getRegion(userCurrentLocation.current, geoState.distance),500);
}} />

In my code I have a geoState Redux state that contains distance in KM, and a function to convert userCurrentLocation and that distance to a MapView Region object. How you obtain that Region from userCurrentLocation is up to you. I just copied my code here for pleteness.

You must not use the userCurrentLocation in rendering logic, because as per documentation it can lead to unpredictable results.

本文标签: javascriptonUserLocationChange changes React Native Maps regionStack Overflow