React Native Maps: Каков наилучший способ реализации перетаскиваемого маркера? - PullRequest
0 голосов
/ 23 января 2020

У меня есть карта, на которой мне нужно добавить перетаскиваемый маркер, чтобы пользователь мог выбрать точку.

Если я выберу обычный метод

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

Это не очень плавная обратная связь для пользователя, так как маркер должен быть сначала нажат на долгое время, прежде чем его можно перетаскивать, а также он не может быть перетащен за пределы текущих границ карты, т.е. пользователю необходимо вручную прокрутить карту в другой регион, прежде возможность разместить маркер там.

Так что я нашел обходной путь, следуя этой концепции: 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>

Это работает почти идеально, за исключением факта Я использую отдельную функцию, используя сервис геолокации, чтобы получить текущее местоположение пользователя и поместить туда маркер

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})
}

Когда эта функция возвращает местоположение, маркер перемещается в правильную точку, НО, карта не прокручивает область, в которой находится маркер, так как initialRegion не меняет область после монтирования.

Если я использую region вместо o f initialRegion, карта вообще не прокручивается, так как обратный вызов onRegionChange постоянно меняет состояние и, вероятно, конфликтует с region prop.

Что может быть лучшим обходным решением для всех проблем

Ответы [ 2 ]

0 голосов
/ 24 января 2020

Лучшим обходным решением будет использование react-native-location-view

. Он предоставляет вам перетаскиваемую карту, и вы можете легко получить местоположение, выбранное маркером.

Вы можете сослаться https://www.npmjs.com/package/react-native-location-view

0 голосов
/ 23 января 2020

enter image description here Лучший способ - показать маркер в центре экрана, поместив его в абсолютное положение. Подобно этому

        <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',
  },

Теперь вы можете перетащить карту в любое место. Который покажет эффект, как маркер движется. Но карта движется в фактическом. Теперь используйте функцию onRegionChangeComplete для преобразования обновленного латланга в адрес. И вы можете показать этот конвертированный адрес над маркером, как на снимке.

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]
...