Flutter Web地图标记图片加载失败:意外空值错误
Flutter Web中MapLibre GL自定义标记加载成功但无法显示,
addSymbol抛出Unexpected null value异常 环境详情
- Flutter版本:3.5.4
- 依赖配置:
dependencies: flutter: sdk: flutter flutter_radar: ^3.12.3 flutter_map: ^5.0.0 latlong2: ^0.9.0 cupertino_icons: ^1.0.8 http: ^1.2.2 http_client: ^1.5.3 vector_map_tiles: ^6.0.2 maplibre_gl: ^0.20.0
- pubspec.yaml资源配置:
flutter: assets: - images/marker.png
- 图片路径:
project/images/marker.png
代码实现
以下是onMapCreated函数及加载标记的辅助方法:
import 'dart:typed_data'; import 'package:flutter/services.dart'; import 'package:maplibre_gl/maplibre_gl.dart'; Future<void> _onMapCreated(MapLibreMapController controller) async { print('[DEBUG] Entering _onMapCreated'); try { const imagePath = 'images/marker.png'; print('[DEBUG] Loading marker image from path: $imagePath'); final Uint8List markerImage = await _loadMarkerImage(imagePath); print('[DEBUG] Marker image loaded successfully'); await controller.addImage('marker', markerImage); print('[DEBUG] Marker image added to map'); const markerPosition = LatLng(40.7342891, -73.9910334); print('[DEBUG] Adding marker at: ${markerPosition.latitude}, ${markerPosition.longitude}'); await controller.addSymbol( SymbolOptions( geometry: markerPosition, iconImage: 'marker', iconSize: 1.0, ), ); print('[DEBUG] Marker added successfully'); } catch (e, stackTrace) { print('[ERROR] Exception in _onMapCreated: $e'); print(stackTrace); } } Future<Uint8List> _loadMarkerImage(String path) async { print('[DEBUG] Loading image from path: $path'); try { final ByteData data = await rootBundle.load(path); print('[DEBUG] Image loaded from assets: $path'); return data.buffer.asUint8List(); } catch (e) { print('[ERROR] Failed to load marker image from path: $path'); throw Exception('[ERROR] Asset not found or invalid: $path'); } }
日志信息
图片加载成功,但标记未添加到地图,日志如下:
1736194029179 [stdout] [DEBUG] Map created successfully 1736194029179 [stdout] [DEBUG] Entering _onMapCreated 1736194029179 [stdout] [DEBUG] Loading marker image 1736194029179 [stdout] [DEBUG] Entering _loadMarkerImage 1736194029180 [stdout] [DEBUG] Loading image from path: packages/portal_package/assets/images/marker.png 1736194029255 [stdout] [DEBUG] Image loaded from assets: packages/portal_package/assets/images/marker.png 1736194029255 [stdout] [DEBUG] Marker image loaded successfully 1736194029255 [stdout] [DEBUG] Adding marker image to map 1736194029262 [stdout] [DEBUG] Marker image added to map 1736194029262 [stdout] [DEBUG] Adding marker symbol to map at: 40.7342891, -73.9910334 1736194029263 [stdout] [ERROR] Exception in _onMapCreated: Unexpected null value.
已尝试的解决方法
- 确认
images/marker.png文件存在且与pubspec.yaml路径一致; - 执行
flutter clean和flutter pub get重建项目; - 验证
_loadMarkerImage步骤中图片加载成功; - 测试
flutter run -d chrome和生产构建flutter build web。
问题
图片加载成功但标记仍不显示,如何修复addSymbol步骤中的Unexpected null value异常?
解决方案
1. 适配Web端图片加载逻辑
MapLibre GL在Web端对Uint8List格式的图片兼容性有限,改用HTML原生API加载图片后再转成Uint8List:
import 'dart:typed_data'; import 'dart:html' as html; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; Future<Uint8List> _loadMarkerImage(String path) async { if (kIsWeb) { final img = html.HtmlImageElement(); // Web端资源路径修正:pubspec配置的images/marker.png对应打包后的assets/images/marker.png img.src = 'assets/$path'; await img.onLoad.first; final canvas = html.CanvasElement(width: img.width, height: img.height); final ctx = canvas.context2D; ctx.drawImage(img, 0, 0); final blob = await canvas.toBlob('image/png'); return Uint8List.fromList(await blob!.arrayBuffer()); } else { final ByteData data = await rootBundle.load(path); return data.buffer.asUint8List(); } }
2. 等待地图完全初始化
onMapCreated触发时地图可能未完全加载完成,等待地图进入空闲状态后再添加标记:
Future<void> _onMapCreated(MapLibreMapController controller) async { print('[DEBUG] Entering _onMapCreated'); try { // 等待地图空闲状态(资源加载完成) await controller.onMapIdle.first; // 后续图片加载和标记添加逻辑保持不变 const imagePath = 'images/marker.png'; print('[DEBUG] Loading marker image from path: $imagePath'); final Uint8List markerImage = await _loadMarkerImage(imagePath); print('[DEBUG] Marker image loaded successfully'); await controller.addImage('marker', markerImage); print('[DEBUG] Marker image added to map'); const markerPosition = LatLng(40.7342891, -73.9910334); print('[DEBUG] Adding marker at: ${markerPosition.latitude}, ${markerPosition.longitude}'); await controller.addSymbol( SymbolOptions( geometry: markerPosition, iconImage: 'marker', iconSize: 1.0, ), ); print('[DEBUG] Marker added successfully'); } catch (e, stackTrace) { print('[ERROR] Exception in _onMapCreated: $e'); print(stackTrace); } }
3. 升级MapLibre GL包版本
当前使用的maplibre_gl: ^0.20.0版本存在Web端已知兼容性问题,升级到最新稳定版本(如^0.26.0):
修改pubspec.yaml:
dependencies: # ...其他依赖 maplibre_gl: ^0.26.0
执行flutter pub upgrade maplibre_gl更新依赖。
4. 修正Package资源路径(若项目为Package)
日志显示图片路径为packages/portal_package/assets/images/marker.png,说明当前项目是Package,需修正图片路径和pubspec配置:
- 代码中路径改为:
const imagePath = 'packages/portal_package/images/marker.png';
- pubspec.yaml资源配置改为:
flutter: assets: - packages/portal_package/images/marker.png
内容的提问来源于stack exchange,提问作者Edward Wynman
相关产品推荐
相关产品推荐

