我在expo的MapView上遇到问题,这是我目前无法更改customMapStyle。我已经尝试了几种解决方法,但对我而言它们都不可行。仅供参考:如果我在安装组件之前设置customMapStyle,则地图样式json可以完美工作。我试图通过这种方式从父组件上卸载并重新安装mapView,从而可以更改地图的样式。但是我觉得这不是解决此问题的合适方法。
特定于错误:
<MapView
style={{ flexGrow: 1 }}
ref={ref => (this.mapRef = ref)}
initialRegion={initialRegion}
provider={MapView.PROVIDER_GOOGLE}
customMapStyle={this.state.mapStyle}
>
<MapView.Marker
draggable
coordinate={markerCoordinate}
onDragEnd={e => this.onMarkerPositionChange(e)}
/>
</MapView>
完整代码:
import React, { Component } from "react";
import {
Alert, View, Button, Text, StyleSheet,
} from "react-native";
import { connect } from "react-redux";
import { bindActionCreators } from "redux";
import {
Location, Permissions, MapView, Components,
} from "expo";
import * as UserActions from "../actions/userActions";
import { getAddress } from "../lib/mapsApi";
import MapHeader from "../components/MapHeader";
import MapFooter from "../components/MapFooter";
const mapStyleBlack = require("../constants/mapStyle.json");
const PROVIDER_GOOGLE = MapView;
export class Map extends Component {
constructor(props) {
super(props);
this.state = {
gpsLocation: undefined,
markerLocation: undefined,
mapStyle: mapStyleBlack,
rerender: false,
address: {
city: "",
district: "",
street: "",
country: "",
postalCode: "",
avenue: "",
},
};
this.askPermission = this.askPermission.bind(this);
this.getCurrentLocation = this.getCurrentLocation.bind(this);
this.onMarkerPositionChange = this.onMarkerPositionChange.bind(this);
this.onPressLocate = this.onPressLocate.bind(this);
this.nextScreen = this.nextScreen.bind(this);
this.rerender = this.rerender.bind(this);
}
componentDidMount() {
this.getCurrentLocation();
}
onPressLocate() {
this.getCurrentLocation();
this.mapRef.animateToCoordinate(this.state.gpsLocation);
}
async onMarkerPositionChange(e) {
const { latitude, longitude } = e.nativeEvent.coordinate;
this.setState({ markerLocation: e.nativeEvent.coordinate });
const address = await getAddress(latitude, longitude);
this.setState({ address });
}
getCurrentLocation = async () => {
if (!this.askPermission()) return;
const currentPosition = await Location.getCurrentPositionAsync();
const {
coords: { latitude, longitude },
} = currentPosition;
this.setState({ gpsLocation: { latitude, longitude } });
this.setState({ markerLocation: { latitude, longitude } });
const address = await getAddress(latitude, longitude);
this.setState({ address });
};
rerender() {
this.state.mapStyle === undefined
? this.setState({ mapStyle: mapStyleBlack })
: this.setState({ mapStyle: undefined });
console.log(this.state.mapStyle);
}
async askPermission() {
console.log(this.state);
const { status } = await Permissions.askAsync(Permissions.LOCATION);
if (status !== "granted") {
Alert.alert(
"Permission error",
"Permission to access location was denied",
[
{ text: "Give Permission", onPress: async () => console.log("Permission given") },
{ text: "Ok" },
],
{ cancelable: false },
);
return false;
}
return true;
}
nextScreen() {
this.props.getUserAddress(this.state.address);
this.props.navigation.navigate("AddressNav");
}
render() {
const { gpsLocation, markerLocation } = this.state;
if (!gpsLocation || !markerLocation) {
return <View />;
}
const initialRegion = {
latitude: gpsLocation.latitude,
longitude: gpsLocation.longitude,
latitudeDelta: 0.01,
longitudeDelta: 0.01,
};
const markerCoordinate = {
latitude: markerLocation.latitude,
longitude: markerLocation.longitude,
};
return (
<View style={styles.fullWidthHeight}>
<MapHeader onPressMapStyleButton={this.rerender} onPressLocateButton={this.onPressLocate} />
<MapView
style={{ flexGrow: 1 }}
ref={ref => (this.mapRef = ref)}
initialRegion={initialRegion}
provider={MapView.PROVIDER_GOOGLE}
customMapStyle={this.state.mapStyle}
>
<MapView.Marker
draggable
coordinate={markerCoordinate}
onDragEnd={e => this.onMarkerPositionChange(e)}
/>
</MapView>
<MapFooter address={this.state.address} onClickNext={this.nextScreen} />
</View>
);
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(UserActions, dispatch);
}
export default connect(
undefined,
mapDispatchToProps,
)(Map);
const styles = StyleSheet.create({
fullWidthHeight: {
width: "100%",
height: "100%",
},
});
/*
const styles = StyleSheet.create({
headerContainer: {
flex: 10,
backgroundColor: "#242424",
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
shadowColor: "black",
shadowOffset: { width: 0, height: 6 },
shadowOpacity: 0.5,
shadowRadius: 3,
elevation: 1,
},
footerTextContainer: {
flex: 6,
alignItems: "flex-start",
justifyContent: "center",
paddingLeft: 15,
height: "100%",
},
footerButtonContainer: {
flex: 2,
alignItems: "center",
height: "100%",
justifyContent: "center",
},
footerText: {
color: "rgba(255,255,255,1)",
fontFamily: "avenir-regular",
fontSize: 14,
},
});
export default MapFooter;
const headerContainer = {
};
const headerText = {
color: "rgba(255,255,255,1)",
fontFamily: "avenir-demi",
fontSize: 16,
};
const styles = StyleSheet.create({
fullWidthHeight: {
width: "100%",
height: "100%",
},
});
*/