动态更改customMapStyle

时间:2018-07-28 00:56:54

标签: react-native expo react-native-maps

我在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%",
  },
});
 */

0 个答案:

没有答案
相关问题