Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Native Maps: What's the best way to implement a draggable marker?

I have a map in which I need to add a draggable marker to allow the user to pick a point.

If I choose the conventional method of

<MapView
initialRegion={{
....
}}>
    <Marker coordinate={this.state.coordinates} draggable />
</MapView

It's not a very smooth feedback for the user, since the marker first needs to be long-pressed before being draggable, and also it cannot be dragged beyond the current boundaries of the map, i.e. the user needs to manually scroll the map to a different region before being able to place the marker there.

So I found a workaround by following this concept: https://alizahid.dev/blog/keep-marker-in-center-and-move-map-around-it

<MapView
initialRegion={{
latitudeDelta: 0.02,
longitudeDelta: 0.02,
latitude: this.state.coordinates.latitude,
longitude: this.state.coordinates.longitude
}}
onRegionChange={(result) => this.setState({coordinates: result})}
style={{height: 300}}
>
    <Marker coordinate={this.state.coordinates} />
</MapView>

This works almost perfect, except for the fact I'm using a separate function using Geolocation service to get the user's current location and place the marker there

componentDidMount() {
Geolocation.getCurrentPosition((position) => {
                this.setState({
                    coordinates: {
                        latitude: position.coords.latitude,
                        longitude: position.coords.longitude
                    }
                });
            },
            (error) => {
                console.log(error);
                alert("Couldn't get GPS location. Please try again or choose pickup point manually.");
            },
            { enableHighAccuracy: true, maximumAge: 10000, timeout: 10000, showLocationDialog: true, forceRequestLocation: true})
}

When this function returns the location, the marker is moved to the correct point, BUT, the map does not scroll to the region where the marker is placed, since initialRegion does not change the region after mounting.

If I use region instead of initialRegion, the map does not scroll at all, since the onRegionChange callback is changing the state continuously and probably conflicting with the region prop.

What could be the best workaround against all the issues?

like image 657
Tanmay Vij Avatar asked Oct 15 '25 16:10

Tanmay Vij


2 Answers

enter image description hereThe best way is to show a marker in centre of screen by positioning it absolute.Like this

        <View style={styles.markerFixed}>
               <Icon
            style={{
              color: '#B11C01',
            }}
            size={30}
            name={'map-marker-alt'}
            solid
          />
        </View>

 markerFixed: {
    left: 0,
    right: 0,
    marginLeft: 0,
    marginTop: 0,
    position: 'absolute',
    top: '40%',
    alignItems: 'center',
  },

Now you can drag your map to any location.Which will show effect like marker is moving.But map is moving in actual.Now use onRegionChangeComplete function to convert updated latlang to address.And you can show that converted address above the marker like in shot.

import Geocoder from 'react-native-geocoding';
 <MapView
            style={styles.mapStyle}
              provider={PROVIDER_GOOGLE}
              region={{
                latitude: lat,
                longitude: long,
                latitudeDelta: 0.0922 / 10,
                longitudeDelta: 0.0421 / 10,
              }}
              onRegionChangeComplete={this.onRegionChange}
            />

    convertToAddress() {
        let {lat, long} = this.state;
        if (this.state.firstIndication === 0) {
          this.setState({firstIndication: 1});
          return;
        }
        Geocoder.from(lat, long)
          .then(json => {
            var addressComponent = json.results[0].address_components[0];
            this.setState({name: addressComponent.long_name});
          })
          .catch(error => console.warn(error));
      }[![enter image description here][1]][1]
like image 197
Abdul Basit Avatar answered Oct 18 '25 07:10

Abdul Basit


The best workaround would be using react-native-location-view

It provides you a draggable map and you can easily get the location whatever you choose by the marker.

You can refer https://www.npmjs.com/package/react-native-location-view

like image 21
Deepak N Avatar answered Oct 18 '25 05:10

Deepak N