Flutter中如何用google_maps_flutter创建带侧边标签的地图标记?
解决google_maps_flutter标记旁常驻标题+点击弹窗需求
先说明为啥改map_style.json没用
你改的map_style.json里的elementType labels控制的是地图原生自带的标签(比如道路名、地名这类),完全管不到你自己添加的自定义Marker,所以不管怎么调都不会生效。
下面给你两个可行方案:
方案一:用LabelMarker(你提到的方案,调样式就能用)
虽然默认样式有点怪,但调整参数就能贴近谷歌地图效果,而且是官方支持的方式,步骤如下:
- 把原来的
Marker换成LabelMarker,直接通过label参数设置常驻标题,同时调整样式优化观感:
LabelMarker( markerId: MarkerId('marker_1'), position: LatLng(37.7749, -122.4194), label: '旧金山', // 自定义样式,让标签更顺眼 textStyle: TextStyle( fontSize: 14, color: Colors.black, fontWeight: FontWeight.w500, backgroundColor: Colors.white.withOpacity(0.9), padding: EdgeInsets.symmetric(horizontal: 6, vertical: 2), ), )
- 实现点击弹窗:给
GoogleMap加onMarkerTap事件,用状态变量控制InfoWindow的显示(可以用一个隐藏的Marker来承载InfoWindow):
bool _showInfoWindow = false; LatLng _infoPos = LatLng(0,0); String _infoContent = ''; // 地图组件部分 GoogleMap( onMarkerTap: (markerId) { if (markerId.value == 'marker_1') { _infoPos = LatLng(37.7749, -122.4194); _infoContent = '美国加利福尼亚州的港口城市'; _showInfoWindow = true; setState(() {}); } }, onTap: (_) { // 点击空白处关闭弹窗 _showInfoWindow = false; setState(() {}); }, markers: { LabelMarker(...), // 上面定义的带标签的标记 if (_showInfoWindow) Marker( markerId: MarkerId('temp_info'), position: _infoPos, infoWindow: InfoWindow(title: '旧金山', snippet: _infoContent), visible: false, // 只显示弹窗,隐藏标记本身 ), }, )
方案二:自定义带文字的Marker图标(完全控制样式)
如果LabelMarker怎么调都不满意,你可以自己生成带标题的图片当Marker图标,完全复刻谷歌地图的标签样式:
- 写个方法生成带文字的图片:
Future<BitmapDescriptor> makeMarkerLabel(String label) async { final recorder = PictureRecorder(); final canvas = Canvas(recorder); final textPainter = TextPainter( text: TextSpan( text: label, style: TextStyle( fontSize: 14, color: Colors.black87, fontWeight: FontWeight.w500, ), ), textDirection: TextDirection.ltr, ); textPainter.layout(); // 绘制白色背景框,带点圆角更自然 final bgRect = Rect.fromLTWH(0, 0, textPainter.width + 10, textPainter.height + 6); canvas.drawRRect( RRect.fromRectAndRadius(bgRect, Radius.circular(3)), Paint()..color = Colors.white, ); // 绘制文字 textPainter.paint(canvas, Offset(5, 3)); final image = await recorder.endRecording().toImage( bgRect.width.toInt(), bgRect.height.toInt(), ); final byteData = await image.toByteData(format: ImageByteFormat.png); return BitmapDescriptor.fromBytes(byteData!.buffer.asUint8List()); }
- 在页面初始化时生成图标,然后用普通Marker使用:
BitmapDescriptor? _customMarker; @override void initState() { super.initState(); makeMarkerLabel('旧金山').then((icon) { setState(() => _customMarker = icon); }); } // 地图里的Marker if (_customMarker != null) Marker( markerId: MarkerId('marker_1'), position: LatLng(37.7749, -122.4194), icon: _customMarker!, infoWindow: InfoWindow(title: '旧金山', snippet: '详细信息'), )
这个方案能完全自定义标签的样式、背景、文字效果,和谷歌地图原生的标记标签几乎一样。
内容的提问来源于stack exchange,提问作者Vítor Fraporti Rosmann
相关产品推荐
相关产品推荐

