Read the original article:Add Multiple Markers with Custom Styles on HarmonyOS Map
Add Multiple Markers with Custom Styles on HarmonyOS Map
Requirement Description
In a map-based application, developers may need to add multiple markers (e.g., user location, vehicle, store) where each marker has a different custom style instead of the default system-provided icons.
Background Knowledge
- Marker is a core feature in Map Kit that supports events such as tap, long press, and drag.
- By default, the system provides a standard marker style, but developers can override it:
- Use
iconproperty ofMarkerOptionsto set custom images. - Use componentSnapshot with a custom
@Buildercomponent to generate pixel maps and apply them to markers.
- Use
- Markers can be added and managed via
MapComponentController.addMarker().
Implementation Steps
Step 1: Define a custom marker style
Use @Builder to build a styled UI component, which will later be converted into an image for the marker.
@Builder
RandomBuilder() {
Row() {
Image($r('app.media.startIcon')).width(18).height(24)
Column() {
Text("200m")
.fontSize(12)
.fontColor("#1f2642")
.fontWeight(FontWeight.Bold)
Text("35 mins")
.fontSize(12)
.fontColor("#1f2642")
.fontWeight(FontWeight.Bold)
.margin({ top: 1 })
}
.margin({ left: 6 })
.alignItems(HorizontalAlign.Start)
Divider()
.vertical(true)
.width(1)
.height(18)
.backgroundColor("#c1cadd")
.margin({ left: 8, right: 8 })
Image($r('app.media.startIcon')).width(18).height(18)
Text("Navigate")
.fontSize(12)
.fontColor("#1f2642")
.fontWeight(FontWeight.Bold)
.margin({ left: 2 })
.onClick(() => {
// handle navigation click
})
}
.margin({ bottom: 3 })
.padding({ left: 6, right: 6, top: 8, bottom: 8 })
.backgroundColor(Color.White)
.borderRadius(12)
.shadow({ radius: 12, color: "#33000000" })
}
Step 2: Convert Builder to PixelMap and add Marker
Use componentSnapshot.createFromBuilder() to generate an image from the custom Builder and pass it as icon in MarkerOptions.
addMarker() {
componentSnapshot.createFromBuilder(() => { this.RandomBuilder() },
async (error: Error, pixmap: image.PixelMap) => {
if (error) {
console.error("error: " + JSON.stringify(error))
return;
}
let markerOptions: mapCommon.MarkerOptions = {
position: {
latitude: 31.984410259206815,
longitude: 118.76625379397866
},
rotation: 0,
visible: true,
zIndex: 0,
alpha: 1,
anchorU: 0.5,
anchorV: 1,
clickable: true,
draggable: true,
flat: false,
icon: pixmap
};
this.mapController?.addMarker(markerOptions);
})
}
By calling addMarker() multiple times with different MarkerOptions and different custom Builders, you can render multiple markers with unique styles.
Test Results
- Multiple markers displayed correctly at specified coordinates.
- Each marker reflected its custom style (icon, text, background).
- Markers responded to tap/drag as expected.
Limitations or Considerations
- Remote icons are not supported directly in
icon. Onlystring,image.PixelMap, orResourcetypes are allowed.- Workaround: Download remote image locally, then use local relative path or Base64 (
data:image/png;base64,...).
- Workaround: Download remote image locally, then use local relative path or Base64 (
- Markers consume memory; avoid using too many high-resolution icons.
- Use
remove()to delete a specific marker, orclear()to remove all markers.
Top comments (0)