如何在react-native中单击地图视图上的任意位置时放置标记

问题描述 投票:0回答:2

我的要求是,当用户单击地图上的任意位置时,我需要在

MaoView
上显示标记,并且还需要获取放置标记的位置的坐标(纬度和经度)。

这是我尝试过的:

class Maps extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            region: {
                latitude: LATITUDE,
                longitude: LONGITUDE,
                latitudeDelta: LATITUDE_DELTA,
                longitudeDelta: LONGITUDE_DELTA
            },
            marker: {
                latlng: {
                    latitude: 17.6868,
                    longitude: 83.2185,
                    latitudeDelta: LATITUDE_DELTA,
                    longitudeDelta: LONGITUDE_DELTA
                }
            }
        };
    }
    
    onMapPress(e) {
        alert("coordinates:" + JSON.stringify(e.nativeEvent.coordinate));

        this.setState({
            marker: [
                {
                    coordinate: e.nativeEvent.coordinate
                }
            ]
        });
    }

    handleMarkerPress(event) {
        const markerID = event.nativeEvent.identifier;
        alert(markerID);
    }

    render() {
        return (
            <MapView
                identifier={"1"}
                ref={component => (this.map = component)}
                provider={this.props.provider}
                style={styles.map}
                region={this.state.region}
                onPress={this.onMapPress.bind(this)}
                //onPress={(event) => this.onMapPress(event)}
                provider={PROVIDER_DEFAULT}
                mapType="standard"
                zoomEnabled={true}
                pitchEnabled={true}
                showsUserLocation={true}
                followsUserLocation={true}
                showsCompass={true}
                showsBuildings={true}
                showsTraffic={true}
                showsIndoors={true}
            >
                <MapView.Marker coordinate={this.state.marker.latlng} />
            </MapView>
        );
    }
}
react-native react-native-maps
2个回答
25
投票

首先,为地图标记取一个空数组。

constructor(props) {
  super(props)

  this.state = {
    region: {
      latitude: LATITUDE, 
      longitude: LONGITUDE,
      latitudeDelta: LATITUDE_DELTA,
      longitudeDelta: LONGITUDE_DELTA
    },
    markers: []        // Here it is
  }
}

然后将单击位置的坐标作为新标记推送到数组中。最后,在您的

<MapView>
中,渲染所有标记:

<MapView style={styles.map} region={this.state.region}
onPress={(e) => this.setState({ markers: [...this.state.markers, { latlng: e.nativeEvent.coordinate }] })}>
{
    // loop through markers array & render all markers
    this.state.markers.map((marker, i) => (
        <MapView.Marker coordinate={marker.latlng} key={i} />
    ))
}
</MapView>

每当您单击地图上的任意位置时,该位置的坐标将被添加到

markers
数组中,并且当
state
更新时,将再次调用
render()
函数,并且所有标记将被放置在地图上,包括新标记。


编辑
@FortuneCookie的评论:

仅在地图上显示一个标记,当用户点击其他位置时 其他标记被删除,就像掉落大头针一样。

就简单多了。首先,将状态下的

markers
数组更改为单个
marker

constructor(props) {
  super(props)

  this.state = {
    region: {
      latitude: LATITUDE, 
      longitude: LONGITUDE,
      latitudeDelta: LATITUDE_DELTA,
      longitudeDelta: LONGITUDE_DELTA
    },
    // markers: []        Change this
    marker: null          // to this
  }
}

对于

<MapView>
,只需更改其子项和
onPress
事件即可。

<MapView style={styles.map} region={this.state.region}
onPress={(e) => this.setState({ marker: e.nativeEvent.coordinate })}>
{
      // if state contains marker variable with a valid value, render the marker
      this.state.marker &&
      <MapView.Marker coordinate={this.state.marker} />
}
</MapView>

您不必将多个标记放入数组中,然后循环遍历它。相反,您只需将所选位置的坐标作为单个标记放置到

state
中,然后(如果标记存在)然后将其渲染在地图上。它将自动将所选位置设置为状态并删除任何先前选择的位置。


4
投票

对于功能组件

const [marker, setMarker] = useState(null);
<MapView
  //   ref={data}
  provider={PROVIDER_GOOGLE} // remove if not using Google Maps
  style={styles.map}
  region={region}
  zoomEnabled={true}
  maxZoomLevel={zoom - 3}
  minZoomLevel={2}
  scrollEnabled={true}
  showsScale={true}
  zoomControlEnabled={true}
  zoomTapEnabled={true}
  // mapType={'satellite'}
  rotateEnabled={false}
  showsUserLocation={true}
  userLocationUpdateInterval={5000}
  showsMyLocationButton={true}
  loadingEnabled={true}
  showsCompass={true}
  onPress={(e) => setMarker(e.nativeEvent.coordinate)}
>
  {marker != null ? (
    <Marker draggable coordinate={marker} onPress={() => Alert.alert("test")} />
  ) : null}
</MapView>
© www.soinside.com 2019 - 2024. All rights reserved.