react-native-maps 自定义地图样式

react-native-maps custom map style

我使用 google 地图样式向导创建了 json。然后,我将其设置为渲染下的常量,并将该常量设置为我的 MapView 样式,但当我这样做时它什么也不渲染。

我不确定这个问题,理想情况下我希望将样式放在一个单独的文件中,但我试图从小处着手。

如何解决当前遇到的问题以及从单独的文件中导入和使用样式?

这是一个 snack of my code 重现我的确切错误以及下面的代码。

export default class Map extends React.Component {

 
  render() {
    const mapStyle = [
      {
        "featureType": "landscape.man_made",
        "elementType": "labels.icon",
        "stylers": [
          {
            "visibility": "off"
          }
        ]
      },
      {
        "featureType": "poi.attraction",
        "elementType": "labels.icon",
        "stylers": [
          {
            "visibility": "off"
          }
        ]
      },
      {
        "featureType": "poi.business",
        "elementType": "labels.icon",
        "stylers": [
          {
            "visibility": "off"
          }
        ]
      },
      {
        "featureType": "poi.business",
        "elementType": "labels.text",
        "stylers": [
          {
            "visibility": "on"
          }
        ]
      },
      {
        "featureType": "poi.government",
        "elementType": "labels.icon",
        "stylers": [
          {
            "visibility": "off"
          }
        ]
      }
    ]

    return (
     <View style={{...StyleSheet.absoluteFillObject}}>
      <MapView
        style={mapStyle}
        provider={PROVIDER_GOOGLE}>
      </MapView>

      </View>
    );
  }
}

自定义 google 地图样式必须传递给 customMapStyle 道具,您需要在正常 [=18= 中设置特定的 widthheight ] MapView 的道具。设置 absoluteFillObject 与您想象的不同,根据 react-native documentation

Currently, there is no difference between using absoluteFill vs. absoluteFillObject.

因此,absoluteFill 适用于以下用例。

A very common pattern is to create overlays with position absolute and zero positioning (position: 'absolute', left: 0, right: 0, top: 0, bottom: 0), so absoluteFill can be used for convenience and to reduce duplication of these repeated styles.

这将不设置高度和宽度!我们需要手动执行此操作,记录在案 here.

以下解决了您的问题。

const styles = ScaledSheet.create({
  map: {
width: Dimensions.get('window').width,
    height: Dimensions.get('window').height,
    
  },
...

JSX 组件。

return (
     <View style={{...StyleSheet.absoluteFillObject}}>
      <MapView
        style={styles.map}
        customMapStyle={mapStyle}
        provider={PROVIDER_GOOGLE}>
      </MapView>

      </View>
    );

这是完整的解决方案。

export default class Map extends React.Component {

  render() {
    const mapStyle = [
      {
        "featureType": "landscape.man_made",
        "elementType": "labels.icon",
        "stylers": [
          {
            "visibility": "off"
          }
        ]
      },
      {
        "featureType": "poi.attraction",
        "elementType": "labels.icon",
        "stylers": [
          {
            "visibility": "off"
          }
        ]
      },
      {
        "featureType": "poi.business",
        "elementType": "labels.icon",
        "stylers": [
          {
            "visibility": "off"
          }
        ]
      },
      {
        "featureType": "poi.business",
        "elementType": "labels.text",
        "stylers": [
          {
            "visibility": "on"
          }
        ]
      },
      {
        "featureType": "poi.government",
        "elementType": "labels.icon",
        "stylers": [
          {
            "visibility": "off"
          }
        ]
      }
    ]
    
    return (
     <View style={{...StyleSheet.absoluteFillObject}}>
      <MapView
        style={styles.map}
        customMapStyle={mapStyle}
        provider={PROVIDER_GOOGLE}>
      </MapView>

      </View>
    );
  }
}

const styles = ScaledSheet.create({
  map: {
width: Dimensions.get('window').width,
    height: Dimensions.get('window').height,
    
  },
  bubble: {
    justifyContent: 'center',
    alignItems: 'center',
    padding: 15,
  },
  carousel: {
    position: 'absolute',
    top: scale(625)
  },
  cardContainer: {
    backgroundColor: '#d1cfcf',
    height: scale(40),
    width: scale(300),
    borderRadius: 10,
    alignSelf: 'center',
    alignItems: 'center',
    justifyContent: 'center',
  },

  name: {
    color: 'black',
    fontSize: 22,

  }
});

在单独的文件中定义 customMapStyle 是纯 JS,可以按如下方式完成。

定义一个新文件,命名为CustomMapStyle.js并添加以下内容。

export const CustomMapStyle = [
      {
        "featureType": "landscape.man_made",
        "elementType": "labels.icon",
        "stylers": [
          {
            "visibility": "off"
          }
        ]
      },
      {
        "featureType": "poi.attraction",
        "elementType": "labels.icon",
        "stylers": [
          {
            "visibility": "off"
          }
        ]
      },
      {
        "featureType": "poi.business",
        "elementType": "labels.icon",
        "stylers": [
          {
            "visibility": "off"
          }
        ]
      },
      {
        "featureType": "poi.business",
        "elementType": "labels.text",
        "stylers": [
          {
            "visibility": "on"
          }
        ]
      },
      {
        "featureType": "poi.government",
        "elementType": "labels.icon",
        "stylers": [
          {
            "visibility": "off"
          }
        ]
      }
    ]

然后如下使用。

import {CustomMapStyle} from './CustomMapStyle'

...

render() {    
    return (
     <View style={{...StyleSheet.absoluteFillObject}}>
      <MapView
        style={styles.map}
        customMapStyle={CustomMapStyle}
        provider={PROVIDER_GOOGLE}>
      </MapView>

      </View>
    );
  }

我更新了your snack here

最终结果。