文章目录前言一、addMapMaker 方法解析二、MarkerOptions 每个参数详解2.1 position坐标位置2.2 anchor锚点2.3 icon自定义图标2.4 flat贴地模式2.5 zIndex层叠顺序2.6 alpha透明度2.7 collisionRule碰撞规则三、批量添加 Marker四、Marker 点击事件五、信息窗口InfoWindow六、底部弹窗关闭时重置动画七、完整的 Marker 生命周期总结前言地图上那些能点击的图标叫做Marker标记是地图应用最核心的 UI 元素之一。在附近加油站里每个加油站在地图上都有一个自定义图标加油站 SVG 图案点击后标记会放大底部列表也会出现。这篇文章详细讲 Marker 的添加、自定义图标配置、信息窗口显示以及点击事件处理。项目预览一、addMapMaker 方法解析// MapUtil.etsasyncaddMapMaker(latitude:number,longitude:number,mapController:map.MapComponentController):Promisevoid{letmarkerOptions:mapCommon.MarkerOptions{position:{latitude:latitude,longitude:longitude},rotation:0,// 旋转角度0度即不旋转visible:true,// 是否可见zIndex:0,// 层叠顺序alpha:1,// 透明度1完全不透明anchorU:0.5,// 锚点X0-10.5水平居中anchorV:1,// 锚点Y0-11底部对齐到坐标点clickable:true,// 是否可点击flat:true,// 是否贴地随地图倾斜icon:station.svg,// 自定义图标SVG文件名collisionRule:mapCommon.CollisionRule.NAME,// 碰撞规则};// 添加 MarkerawaitmapController.addMarker(markerOptions);}二、MarkerOptions 每个参数详解2.1 position坐标位置position:{latitude:latitude,longitude:longitude}Marker 在地图上显示的位置使用 GCJ02 坐标中国境内。2.2 anchor锚点anchorU:0.5,// 水平方向锚点0左边, 0.5中间, 1右边anchorV:1,// 垂直方向锚点0顶部, 0.5中间, 1底部锚点决定 Marker 图标的哪个点对应地图坐标anchorU0.5, anchorV1 的效果 ┌────────────┐ │ │ │ [图标] │ │ │ └─────●──────┘ ↑ 图标底部中央对准坐标点像图钉一样对于加油站这种图标anchorV1底部对齐让图标的底部尖端精确指向坐标点视觉上更准确。2.3 icon自定义图标icon:station.svg,// 使用 SVG 文件作为图标icon指定图标文件名文件放在resources/base/media/目录下。支持 PNG、SVG 等格式。为什么选 SVG格式优点缺点PNG支持复杂图案放大会模糊需要提供2x/3x多分辨率SVG矢量任意放大不失真文件小不支持过于复杂的效果地图标记需要在不同缩放级别下保持清晰SVG 是更好的选择。2.4 flat贴地模式flat:true,flat: true标记贴在地图表面地图倾斜时标记也跟着倾斜更立体的感觉flat: false默认标记始终面向用户始终垂直于屏幕2.5 zIndex层叠顺序zIndex:0,当多个 Marker 重叠时zIndex越大的显示在上层。默认 0如果你希望某个重要标记始终在最上面给它设置更大的 zIndex。2.6 alpha透明度alpha:1,// 1完全不透明0完全透明0.5半透明2.7 collisionRule碰撞规则collisionRule:mapCommon.CollisionRule.NAME,当多个 Marker 在屏幕上位置太近时如何处理碰撞碰撞规则说明NAME按名称决定显示优先级NONE不处理碰撞都显示三、批量添加 Marker// GasStationPage.ets - callback 里this.stationInfoList.forEach(async(stationItem:StationData){awaitmapUtil.addMapMaker(stationItem.latitude,stationItem.longitude,this.mapControllerasmap.MapComponentController);});遍历加油站列表为每个加油站在对应坐标添加一个 Marker。注意这里用的是async forEach——虽然语法上没问题但有一个潜在问题forEach 不能正确等待 async 回调完成。更严谨的写法// 更严谨用 for...of await 确保顺序添加for(letstationItemofthis.stationInfoList){awaitmapUtil.addMapMaker(stationItem.latitude,stationItem.longitude,this.mapControllerasmap.MapComponentController);}对于这个场景并发添加还是顺序添加差别不大forEach写法更简洁但要知道它不是真正的顺序等待。四、Marker 点击事件在 GasStationPage 的 callback 里监听 Marker 点击this.mapController.on(markerClick,(marker){// 1. 显示底部加油站列表this.isShowtrue;// 2. 显示标记的信息窗口弹出小气泡marker.setInfoWindowVisible(true);// 3. 记录当前点击的标记用于后续重置this.curMarkermarker;// 4. 设置放大比例并播放动画this.imageScale1.5;mapUtil.imageAnimation(marker,this.imageScale);// 5. 移动地图到该标记位置mapUtil.moveToCurrentPosition(marker.getPosition().latitude,marker.getPosition().longitude,mapController);});marker 对象的常用方法方法作用marker.getPosition()获取标记的经纬度marker.setInfoWindowVisible(true)显示信息窗口小气泡marker.setAnimation(animation)设置动画marker.startAnimation()启动动画marker.setVisible(true)设置可见性marker.setIcon(newIcon.png)动态更换图标五、信息窗口InfoWindowmarker.setInfoWindowVisible(true);// 显示信息窗口marker.setInfoWindowVisible(false);// 隐藏信息窗口信息窗口是点击 Marker 后弹出的小气泡默认显示 Marker 的 title 和 snippetletmarkerOptions:mapCommon.MarkerOptions{// ...title:中国石化AA站,// 信息窗口标题snippet:N市J区XX大街587号,// 信息窗口副标题};项目里没有设置title和snippet所以信息窗口是空的。调用setInfoWindowVisible(true)只是触发一个空白气泡实际信息展示在底部的bindSheet里。六、底部弹窗关闭时重置动画当底部弹窗关闭时需要把放大的 Marker 恢复原始大小// GasStationPage.ets - bindSheet 的 onWillDismiss 回调.bindSheet($$this.isShow,this.bindBuilder(),{// ...onWillDismiss:((dismissSheetAction:DismissSheetAction){if(this.curMarker){this.imageScale1;// 恢复原始大小mapUtil.imageAnimation(this.curMarker,this.imageScale);// 播放缩小动画}dismissSheetAction.dismiss();// 确认关闭弹窗})});七、完整的 Marker 生命周期页面进入 → init() └─ addMapMaker() × 4 添加4个加油站标记 用户点击标记 └─ on(markerClick) ├─ setInfoWindowVisible(true) 显示气泡 ├─ imageAnimation(scale1.5) 放大动画 ├─ moveToCurrentPosition() 移动镜头 └─ isShow true 显示底部列表 用户关闭底部列表 └─ onWillDismiss └─ imageAnimation(scale1) 缩小恢复总结Marker 是地图的核心 UI 元素创建构建MarkerOptions坐标、图标、锚点、可见性等添加mapController.addMarker(markerOptions)注意是 async 的监听点击mapController.on(markerClick, callback)callback 接收 marker 对象动态操作通过 marker 对象的方法控制显示/隐藏/动画自定义图标使用 SVG锚点anchorV1让图标底部对准坐标点体验更准确。下一篇讲相机动画——地图镜头移动是怎么实现流畅动画效果的。