[鸿蒙2025领航者闯关]HarmonyOS中开发高德地图第二篇:显示第一个地图
本篇教程将带你创建并显示第一个高德地图界面,理解地图组件的基本使用方法。
·
第二篇:显示第一个地图
本篇教程将带你创建并显示第一个高德地图界面,理解地图组件的基本使用方法。
学习目标
- 掌握MapViewComponent组件的使用
- 理解地图生命周期管理
- 学会获取AMap对象进行地图操作
- 实现基本的地图显示
1. 核心概念
1.1 MapViewComponent
MapViewComponent 是高德地图提供的ArkUI组件,用于在页面中显示地图。
1.2 MapView与AMap
- MapView: 地图视图对象,管理地图的生命周期
- AMap: 地图控制对象,用于操作地图(缩放、移动、添加标记等)
1.3 生命周期流程
MapViewComponent创建 → MapViewManager回调 → MapView.onCreate() → getMapAsync() → 获取AMap对象
2. 创建地图页面
2.1 基础代码
创建文件 entry/src/main/ets/pages/Demo01_BasicMap.ets:
import {
AMap,
MapView,
MapViewComponent,
MapViewManager,
MapViewCreateCallback,
CameraUpdateFactory,
LatLng
} from '@amap/amap_lbs_map3d';
import { Constants } from '../common/Constants';
// 地图视图名称常量
const MAP_VIEW_NAME = 'BasicMapDemo';
@Entry
@Component
struct Demo01_BasicMap {
// 地图视图对象
private mapView: MapView | undefined = undefined;
// 地图控制对象
private aMap: AMap | undefined = undefined;
// 页面状态
@State isMapReady: boolean = false;
@State mapInfo: string = '地图加载中...';
/**
* 地图视图创建回调
*/
private mapViewCreateCallback: MapViewCreateCallback =
(mapview: MapView | undefined, mapViewName: string | undefined) => {
// 检查是否是当前页面的地图
if (!mapview || mapViewName !== MAP_VIEW_NAME) {
return;
}
console.info('[BasicMap] MapView created');
this.mapView = mapview;
// 必须调用onCreate初始化地图
this.mapView.onCreate();
// 异步获取AMap对象
this.mapView.getMapAsync((map: AMap) => {
console.info('[BasicMap] AMap ready');
this.aMap = map;
this.isMapReady = true;
// 设置地图初始位置
this.initMapCamera();
// 更新状态信息
this.updateMapInfo();
});
};
/**
* 设置地图初始相机位置
*/
private initMapCamera(): void {
if (!this.aMap) return;
// 创建目标位置(北京天安门)
const center = new LatLng(
Constants.DEFAULT_CENTER_LAT,
Constants.DEFAULT_CENTER_LNG
);
// 移动相机到指定位置和缩放级别
const cameraUpdate = CameraUpdateFactory.newLatLngZoom(
center,
Constants.DEFAULT_ZOOM
);
this.aMap.moveCamera(cameraUpdate);
}
/**
* 更新地图信息显示
*/
private updateMapInfo(): void {
if (!this.aMap) return;
const cameraPosition = this.aMap.getCameraPosition();
if (cameraPosition) {
const target = cameraPosition.target;
this.mapInfo = `中心点: ${target.latitude.toFixed(6)}, ${target.longitude.toFixed(6)}\n缩放级别: ${cameraPosition.zoom.toFixed(1)}`;
}
}
/**
* 页面即将显示时注册回调
*/
aboutToAppear(): void {
console.info('[BasicMap] aboutToAppear');
// 注册地图创建回调
MapViewManager.getInstance()
.registerMapViewCreatedCallback(this.mapViewCreateCallback);
}
/**
* 页面即将销毁时清理资源
*/
aboutToDisappear(): void {
console.info('[BasicMap] aboutToDisappear');
// 注销回调
MapViewManager.getInstance()
.unregisterMapViewCreatedCallback(this.mapViewCreateCallback);
// 销毁地图
if (this.mapView) {
this.mapView.onDestroy();
this.mapView = undefined;
this.aMap = undefined;
}
}
build() {
Column() {
// 标题栏
Row() {
Text('第一个地图')
.fontSize(20)
.fontWeight(FontWeight.Bold)
}
.width('100%')
.height(56)
.padding({ left: 16, right: 16 })
.backgroundColor('#4CAF50')
// 地图容器
Stack() {
// 地图组件
MapViewComponent({ mapViewName: MAP_VIEW_NAME })
.width('100%')
.height('100%')
// 加载状态提示
if (!this.isMapReady) {
Column() {
LoadingProgress()
.width(50)
.height(50)
Text('地图加载中...')
.fontSize(14)
.fontColor('#666')
.margin({ top: 10 })
}
}
// 地图信息面板
if (this.isMapReady) {
Column() {
Text(this.mapInfo)
.fontSize(12)
.fontColor('#333')
}
.padding(10)
.backgroundColor('rgba(255,255,255,0.9)')
.borderRadius(8)
.position({ x: 10, y: 10 })
}
}
.width('100%')
.layoutWeight(1)
// 底部操作栏
Row() {
Button('移动到北京')
.onClick(() => this.moveToBeiJing())
.margin({ right: 10 })
Button('移动到上海')
.onClick(() => this.moveToShanghai())
}
.width('100%')
.height(60)
.justifyContent(FlexAlign.Center)
.backgroundColor('#f5f5f5')
}
.width('100%')
.height('100%')
}
/**
* 移动地图到北京
*/
private moveToBeiJing(): void {
if (!this.aMap) return;
const beijing = new LatLng(39.909187, 116.397451);
const cameraUpdate = CameraUpdateFactory.newLatLngZoom(beijing, 15);
// 使用动画移动
this.aMap.animateCamera(cameraUpdate, 1000);
// 延迟更新信息
setTimeout(() => this.updateMapInfo(), 1100);
}
/**
* 移动地图到上海
*/
private moveToShanghai(): void {
if (!this.aMap) return;
const shanghai = new LatLng(31.230416, 121.473701);
const cameraUpdate = CameraUpdateFactory.newLatLngZoom(shanghai, 15);
// 使用动画移动
this.aMap.animateCamera(cameraUpdate, 1000);
// 延迟更新信息
setTimeout(() => this.updateMapInfo(), 1100);
}
}
3. 配置路由
3.1 修改页面路由配置
在 entry/src/main/resources/base/profile/main_pages.json 中添加页面:
{
"src": [
"pages/Index",
"pages/Demo01_BasicMap"
]
}
4. 关键代码解析
4.1 注册地图创建回调
MapViewManager.getInstance()
.registerMapViewCreatedCallback(this.mapViewCreateCallback);
说明:
- 必须在
aboutToAppear中注册回调 - 通过
mapViewName区分不同的地图实例 - 同一页面可以有多个地图,通过名称区分
4.2 地图生命周期管理
// 创建时初始化
this.mapView.onCreate();
// 销毁时清理
this.mapView.onDestroy();
说明:
onCreate()必须调用,否则地图无法正常显示onDestroy()用于释放资源,防止内存泄漏
4.3 获取AMap对象
this.mapView.getMapAsync((map: AMap) => {
this.aMap = map;
// 在这里进行地图操作
});
说明:
getMapAsync是异步方法,地图准备好后回调- 所有地图操作都需要在获取
AMap对象之后进行
4.4 相机控制
// 直接移动(无动画)
this.aMap.moveCamera(cameraUpdate);
// 动画移动
this.aMap.animateCamera(cameraUpdate, duration);
说明:
moveCamera立即移动,无过渡效果animateCamera带动画效果,更平滑
5. CameraUpdateFactory 方法说明
| 方法 | 说明 |
|---|---|
newLatLng(latLng) |
移动到指定位置,保持当前缩放级别 |
newLatLngZoom(latLng, zoom) |
移动到指定位置和缩放级别 |
zoomIn() |
放大一级 |
zoomOut() |
缩小一级 |
zoomTo(zoom) |
缩放到指定级别 |
newCameraPosition(position) |
使用完整的相机参数 |
6. 运行效果
运行应用后,你将看到:
- 地图显示在屏幕中央
- 左上角显示当前地图中心点坐标和缩放级别
- 点击底部按钮可以平滑切换城市
7. 完整生命周期图示
┌─────────────────────────────────────────────────────┐
│ 页面生命周期 │
├─────────────────────────────────────────────────────┤
│ aboutToAppear() │
│ ↓ │
│ registerMapViewCreatedCallback() │
│ ↓ │
│ MapViewComponent 渲染 │
│ ↓ │
│ mapViewCreateCallback 触发 │
│ ↓ │
│ mapView.onCreate() │
│ ↓ │
│ mapView.getMapAsync() → AMap 对象就绪 │
│ ↓ │
│ 进行地图操作... │
│ ↓ │
│ aboutToDisappear() │
│ ↓ │
│ unregisterMapViewCreatedCallback() │
│ ↓ │
│ mapView.onDestroy() │
└─────────────────────────────────────────────────────┘
常见问题
Q1: 地图显示空白?
A: 检查以下几点:
- API Key是否正确配置
- 是否有网络权限
- 是否调用了
mapView.onCreate()
Q2: 多次进入页面崩溃?
A: 确保在aboutToDisappear中:
- 注销了回调
- 调用了
mapView.onDestroy()
Q3: 地图显示灰色瓦片?
A: 可能是网络问题或API Key配额用尽,检查控制台日志。
本篇小结
本篇教程我们学习了:
- ✅ MapViewComponent组件的基本使用
- ✅ 地图创建回调机制
- ✅ 地图生命周期管理
- ✅ AMap对象的获取和使用
- ✅ 相机位置控制
下一篇我们将学习如何切换地图类型和配置UI控件。
班级
https://developer.huawei.com/consumer/cn/training/classDetail/fd34ff9286174e848d34cde7f512ce22?type=1%3Fha_source%3Dhmosclass&ha_sourceId=89000248
源码地址
https://gitcode.com/daleishen/gaodehmjiaocheng.git
更多推荐


所有评论(0)