You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Google Maps自定义道路样式仅在缩放≤13生效问题求助

问题:Google Maps Flutter自定义道路样式仅在缩放等级13及以下生效,高等级恢复默认

在Flutter应用中使用Google Maps Flutter插件展示地图,通过setMapStyle方法设置自定义样式,将道路颜色改为指定灰色(#BDBDBD)。但发现该样式仅在地图缩放等级13及以下生效,缩放至14、15及更高等级时,道路会恢复为默认黑色,希望自定义道路样式能在所有缩放等级下保持一致。

相关代码如下:

import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'dart:async';

class MapPage extends StatefulWidget {
  final bool smallMap;
  final double latitude;
  final double longitude;

  const MapPage(
      {Key? key,
      this.smallMap = false,
      required this.latitude,
      required this.longitude})
      : super(key: key);

  @override
  _MapPageState createState() => _MapPageState();
}

class _MapPageState extends State<MapPage> {
  bool _mapLoading = true;
  Completer<GoogleMapController> _controllerCompleter =
      Completer<GoogleMapController>();
  String mapStyle = '''
[
    {
        "featureType": "road",
        "elementType": "geometry",
        "stylers": [
            {
                "visibility": "on"
            },
            {
          "color": "#BDBDBD"
            }
        ]
    }
];
  ''';

  @override
  void initState() {
    super.initState();
    applyMapStyle();
  }

  Future<void> applyMapStyle() async {
    final GoogleMapController controller = await _controllerCompleter.future;
    // Apply the map style
    await controller.setMapStyle(mapStyle);
  }

  @override
  Widget build(BuildContext context) {
    final Size size = MediaQuery.of(context).size;

    return Scaffold(
      appBar: AppBar(
        title: Text('Map Page'),
      ),
      body: Stack(
        children: [
          SizedBox(
            height: widget.smallMap
                ? 200
                : MediaQuery.of(context).size.height -
                    kToolbarHeight -
                    MediaQuery.of(context).padding.top,
            child: GoogleMap(
              initialCameraPosition: CameraPosition(
                target: LatLng(widget.longitude, widget.latitude),
                zoom: 13,
              ),
              markers: _buildMarkers(),
              onMapCreated: (GoogleMapController controller) {
                _controllerCompleter.complete(controller);
                setState(() {
                  _mapLoading = false;
                });
              },
            ),
          ),
          if (_mapLoading)
            Container(
              height: size.height,
              width: size.width,
              color: Colors.grey[100],
              child: Center(
                child: CircularProgressIndicator(),
              ),
            ),
        ],
      ),
    );
  }

  Set<Marker> _buildMarkers() {
    return {
      Marker(
        markerId: MarkerId('YourMarkerId'),
        position: LatLng(widget.longitude, widget.latitude),
        infoWindow: InfoWindow(
          title: 'Your Location',
        ),
        icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueRed),
      ),
    };
  }
}

解决方案

1. 问题根源

Google Maps的地图样式系统中,road是父级要素类型,但在高缩放等级(14+)时,地图会加载更细分的道路子类型(如road.highway、road.arterial、road.local、road.highway.controlled_access等),这些子类型的样式优先级高于父级road,因此仅设置road的样式无法覆盖高等级下的子类型默认样式。

另外,当前mapStyle字符串末尾多了一个分号;,这会导致JSON解析异常,也是样式失效的潜在原因。

2. 修改后的地图样式

更新mapStyle,覆盖所有道路相关的要素类型,确保在所有缩放等级下生效:

String mapStyle = '''
[
    // 覆盖所有道路父类型
    {
        "featureType": "road",
        "elementType": "geometry",
        "stylers": [
            {
                "visibility": "on"
            },
            {
                "color": "#BDBDBD"
            }
        ]
    },
    // 覆盖高速公路类子类型
    {
        "featureType": "road.highway",
        "elementType": "geometry",
        "stylers": [
            {
                "visibility": "on"
            },
            {
                "color": "#BDBDBD"
            }
        ]
    },
    // 覆盖主干道类子类型
    {
        "featureType": "road.arterial",
        "elementType": "geometry",
        "stylers": [
            {
                "visibility": "on"
            },
            {
                "color": "#BDBDBD"
            }
        ]
    },
    // 覆盖本地道路类子类型
    {
        "featureType": "road.local",
        "elementType": "geometry",
        "stylers": [
            {
                "visibility": "on"
            },
            {
                "color": "#BDBDBD"
            }
        ]
    },
    // 覆盖高速公路匝道等细分类型
    {
        "featureType": "road.highway.controlled_access",
        "elementType": "geometry",
        "stylers": [
            {
                "visibility": "on"
            },
            {
                "color": "#BDBDBD"
            }
        ]
    }
]
''';

3. 额外优化

确保样式应用逻辑更可靠:当前代码在initState中调用applyMapStyle,但此时地图控制器可能还未初始化,建议将样式应用移到onMapCreated回调中,避免异步等待的潜在问题:

onMapCreated: (GoogleMapController controller) {
  _controllerCompleter.complete(controller);
  // 直接在这里应用样式
  controller.setMapStyle(mapStyle);
  setState(() {
    _mapLoading = false;
  });
},

这样可以确保样式在地图加载完成后立即生效,避免不必要的异步等待。


内容的提问来源于stack exchange,提问作者Bahadur Khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 17:21:13