高德地图 Flutter 插件:跨 Android / iOS / HarmonyOS 的完整实现
高德地图 Flutter 插件实现了 Android/iOS/HarmonyOS 三端支持,解决了官方插件在鸿蒙生态的缺失问题。核心改进包括:1)HarmonyOS原生适配;2)优化自定义地图样式传输方案,将二进制数据传输改为路径引用,显著提升性能并消除卡顿;3)保持与官方API一致,降低迁移成本。该插件支持地图基础功能、覆盖物及POI交互等,开发者可通过Git依赖快速集成,实现跨平台地图功能。项
高德地图 Flutter 插件:跨 Android / iOS / HarmonyOS 的完整实现
背景
高德官方提供了 amap_flutter_map 插件,但仅支持 Android 和 iOS 平台。随着 HarmonyOS NEXT 的发布,Flutter 开发者在鸿蒙生态中缺少一份可用的高德地图插件。
本项目在官方插件的基础上,完整实现了 HarmonyOS 原生适配,使同一套 Flutter 代码可以同时运行在 Android、iOS 和 HarmonyOS 三端。
插件地址: https://gitee.com/dileber/amap_flutter_map
接入方式
在 pubspec.yaml 中通过 Git 依赖引入:
dependencies:
amap_flutter_map:
git:
url: https://gitee.com/dileber/amap_flutter_map.git
支持的功能
地图基础能力
| 功能 | 说明 |
|---|---|
| 地图类型切换 | 普通地图、卫星图、导航图等 |
| 手势控制 | 缩放、滑动、旋转、倾斜 |
| 相机控制 | 移动、缩放、动画过渡 |
| 缩放级别限制 | 最小/最大缩放范围 |
| 地图边界限制 | 限制可滑动区域 |
| 自定义地图样式 | 支持自定义主题切换 |
| 定位蓝点 | 真实 GPS 定位 + 精度圈 |
| 截图 | 地图快照 |
| POI 点击 | 地图 POI 交互 |
覆盖物
| 类型 | 说明 |
|---|---|
| Marker | 支持自定义图标、信息窗口、拖拽 |
| Polyline | 支持颜色、线宽、虚线、大地曲线、纹理 |
| Polygon | 支持填充色、边框色、边框宽度 |
与官方插件的核心差异:自定义地图样式
这是本插件与官方版本最重要的区别。
官方方案:二进制数据传输
官方 CustomStyleOptions 使用 styleData 和 styleExtraData 字段传输二进制数据:
// 官方方式
ByteData styleByteData = await rootBundle.load('assets/default_style.data');
_customStyleOptions.styleData = styleByteData.buffer.asUint8List();
Flutter 层将几 MB 的样式文件通过 Platform Channel 序列化传输到原生层。
本插件方案:路径引用
本插件将 styleData / styleExtraData 替换为 styleDataPath / styleExtraDataPath,仅传递文件名:
// 本插件方式
_customStyleOptions.styleDataPath = "default_style.data";
_customStyleOptions.styleExtraDataPath = "default_style_extra.data";
原生层收到路径后,直接从本地资源目录读取文件:
- Android:从
assets/目录读取 - HarmonyOS:从
resources/rawfile/目录读取
为什么这样做?
1. 性能瓶颈
Uint8List.toString() 会将每个字节逐一输出为字符串。一个 2MB 的样式文件,toString() 会生成类似 [0,1,2,...,255,0,1,...] 的超长字符串,耗时数秒。在 setState 触发的组件重建中,如果 CustomStyleOptions 携带了二进制数据,每次重建都会触发这个比较操作,导致明显的 UI 卡顿。
2. 传输开销
Platform Channel 的 StandardMessageCodec 在序列化大数据时会产生额外的内存拷贝和 GC 压力。样式文件通常有几 MB,每次切换自定义地图都会触发一次完整的序列化-反序列化流程。
3. 路径方案的优势
| 维度 | 二进制传输 | 路径引用 |
|---|---|---|
| Flutter→原生传输大小 | 几 MB | 几十字节 |
toString() 比较耗时 |
数秒 | 瞬间 |
| 内存占用 | 双倍(Flutter + Channel) | 仅原生侧 |
| 切换流畅度 | 明显卡顿 | 无感知 |
资源文件放置
使用路径方案时,需要将样式文件放到原生资源目录:
example/android/app/src/main/assets/
├── default_style.data
└── default_style_extra.data
example/ohos/entry/src/main/resources/rawfile/
├── default_style.data
└── default_style_extra.data
架构设计
┌─────────────────────────────────────────────┐
│ Flutter (Dart) │
│ AMapWidget ──→ MethodChannel ──→ Events │
└──────────────┬──────────────┬───────────────┘
│ │
┌──────────▼──────┐ ┌───▼──────────────┐
│ Android │ │ HarmonyOS │
│ (Java/Kotlin) │ │ (ArkTS) │
│ │ │ │
│ MapController │ │ MapController │
│ AMapPlatformView│ │ AMapView │
│ ConvertUtil │ │ ConvertUtil │
└─────────────────┘ └──────────────────┘
三端共用同一套 Dart 接口,原生层各自实现。开发者无需关心平台差异,调用方式与官方插件完全一致。
快速开始
1. 配置 API Key
AMapWidget(
apiKey: 'your_android_ios_key',
ohosApiKey: 'your_harmonyos_key',
initialCameraPosition: CameraPosition(
target: LatLng(39.90882, 116.39747),
zoom: 13,
),
onMapCreated: (controller) {
_mapController = controller;
},
)
2. 添加 Marker
AMapWidget(
markers: {
Marker(
position: LatLng(39.90882, 116.39747),
title: '北京',
icon: BitmapDescriptor.defaultMarker,
),
},
)
3. 自定义地图样式
// 设置路径(在 initState 中调用)
_customStyleOptions.styleDataPath = "default_style.data";
_customStyleOptions.styleExtraDataPath = "default_style_extra.data";
// 切换开关
setState(() {
_customStyleOptions.enabled = true;
});
总结
本插件在官方 amap_flutter_map 的基础上:
- 补全了 HarmonyOS 原生实现,让 Flutter 高德地图真正跨三端运行
- 优化了自定义地图样式的传输方式,从二进制传输改为路径引用,彻底解决了切换卡顿问题
- 保持了与官方一致的 API 设计,迁移成本为零
如果你正在开发支持 HarmonyOS 的 Flutter 地图应用,这个插件可以直接使用。
更多推荐



所有评论(0)