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
相关产品推荐
相关产品推荐

