如何在Flutter中制作带网络图片的自定义动态Google Map标记
在Flutter中实现带网络图片的自定义Google Map标记
步骤1:添加依赖
在pubspec.yaml中引入所需包:
dependencies: flutter: sdk: flutter google_maps_flutter: ^2.5.0 cached_network_image: ^3.3.0 # 用于缓存网络图片,优化加载体验
步骤2:实现自定义标记生成方法
将网络图片转换成Google Map标记支持的BitmapDescriptor,同时添加圆形底色匹配你需要的效果:
import 'dart:async'; import 'dart:typed_data'; import 'dart:ui' as ui; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; Future<BitmapDescriptor> createCustomMarker(String imageUrl) async { final recorder = ui.PictureRecorder(); final canvas = Canvas(recorder); // 绘制白色圆形背景 final bgPaint = Paint()..color = Colors.white; canvas.drawCircle(const Offset(40, 40), 40, bgPaint); // 加载网络图片 final imageProvider = CachedNetworkImageProvider(imageUrl); final imageCompleter = Completer<ui.Image>(); imageProvider.resolve(const ImageConfiguration()).addListener( ImageStreamListener((info, _) => imageCompleter.complete(info.image)), ); final ui.Image image = await imageCompleter.future; // 将图片裁剪为圆形并绘制 final rect = Rect.fromLTWH(10, 10, 60, 60); final rRect = RRect.fromRectAndRadius(rect, const Radius.circular(30)); canvas.clipRRect(rRect); canvas.drawImage(image, const Offset(10, 10), Paint()); // 转换为BitmapDescriptor final picture = recorder.endRecording(); final markerImage = await picture.toImage(80, 80); final byteData = await markerImage.toByteData(format: ui.ImageByteFormat.png); return BitmapDescriptor.fromBytes(byteData!.buffer.asUint8List()); }
步骤3:在地图中使用自定义标记
初始化地图控制器,加载自定义标记并添加到地图上:
class CustomMarkerMap extends StatefulWidget { const CustomMarkerMap({super.key}); @override State<CustomMarkerMap> createState() => _CustomMarkerMapState(); } class _CustomMarkerMapState extends State<CustomMarkerMap> { final _mapController = Completer<GoogleMapController>(); final Set<Marker> _markers = {}; static const _initialCamera = CameraPosition( target: LatLng(37.42796, -122.08575), zoom: 14.5, ); @override void initState() { super.initState(); _loadMarkers(); } Future<void> _loadMarkers() async { // 替换为你的网络图片地址 final markerIcon = await createCustomMarker("https://example.com/avatar.jpg"); setState(() { _markers.add( Marker( markerId: const MarkerId("user_marker"), position: const LatLng(37.42796, -122.08575), icon: markerIcon, infoWindow: const InfoWindow(title: "用户位置"), ), ); }); } @override Widget build(BuildContext context) { return Scaffold( body: GoogleMap( initialCameraPosition: _initialCamera, markers: _markers, onMapCreated: (controller) => _mapController.complete(controller), ), ); } }
注意事项
- 确保项目配置了网络权限:
- Android:在
AndroidManifest.xml中添加<uses-permission android:name="android.permission.INTERNET"/> - iOS:在
Info.plist中添加网络权限配置(允许任意域名或指定域名)
- Android:在
- 可根据需求调整标记的大小、背景颜色、边框等样式,修改画布绘制逻辑即可
- 如果不需要图片缓存,可替换
CachedNetworkImageProvider为NetworkImage,但前者能更好处理加载失败、占位图等场景
内容的提问来源于stack exchange,提问作者Michael Solomon
相关产品推荐
相关产品推荐

