You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jetpack Compose中创建带自定义文本的Google Maps自定义标记图标

在Jetpack Compose中为Marker组件创建带自定义文本的标记图标

核心思路

普通Marker组件仅支持BitmapDescriptor类型的图标,因此我们需要将基础标记图标与自定义文本合成一张Bitmap,再转换为BitmapDescriptor,以此替代AdvancedMarker的pinConfig实现相同视觉效果,同时保证流畅性。

具体实现步骤

1. 编写BitmapDescriptor生成工具函数

创建工具函数,负责将基础图标与文本合成目标Bitmap,并转换为BitmapDescriptor:

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.drawable.Drawable
import androidx.core.content.ContextCompat
import com.google.android.gms.maps.model.BitmapDescriptor
import com.google.android.gms.maps.model.BitmapDescriptorFactory

fun createCustomMarkerWithText(
    context: Context,
    baseMarkerResId: Int, // 基础标记图标的资源ID
    text: String,
    textSize: Float = 24f,
    textColor: Int = Color.WHITE,
    textBackgroundColor: Int = Color.RED
): BitmapDescriptor {
    // 加载基础标记图标
    val baseDrawable: Drawable? = ContextCompat.getDrawable(context, baseMarkerResId)
        ?: throw IllegalArgumentException("无效的图标资源ID")

    // 创建Bitmap画布
    val bitmap = Bitmap.createBitmap(
        baseDrawable.intrinsicWidth,
        baseDrawable.intrinsicHeight,
        Bitmap.Config.ARGB_8888
    )
    val canvas = Canvas(bitmap)
    baseDrawable.setBounds(0, 0, canvas.width, canvas.height)
    baseDrawable.draw(canvas)

    // 配置文本画笔
    val textPaint = Paint().apply {
        color = textColor
        textSize = textSize
        isAntiAlias = true
        textAlign = Paint.Align.CENTER
        isFakeBoldText = true
    }

    // 计算文本居中位置
    val xPos = canvas.width / 2f
    val yPos = canvas.height / 2f - (textPaint.descent() + textPaint.ascent()) / 2f

    // 绘制文本背景(可选)
    val textBounds = android.graphics.Rect()
    textPaint.getTextBounds(text, 0, text.length, textBounds)
    val bgPaint = Paint().apply {
        color = textBackgroundColor
        isAntiAlias = true
    }
    val bgRadius = maxOf(textBounds.width(), textBounds.height()) / 2f + 8f
    canvas.drawCircle(xPos, yPos, bgRadius, bgPaint)

    // 绘制文本
    canvas.drawText(text, xPos, yPos, textPaint)

    // 转换为Marker所需的BitmapDescriptor
    return BitmapDescriptorFactory.fromBitmap(bitmap)
}

2. 在Compose地图中使用Marker组件

在地图Composable中调用工具函数生成图标,传入Marker的icon参数:

import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import com.google.android.gms.maps.model.CameraPosition
import com.google.android.gms.maps.model.LatLng
import com.google.maps.android.compose.GoogleMap
import com.google.maps.android.compose.Marker
import com.google.maps.android.compose.MarkerState
import com.google.maps.android.compose.rememberCameraPositionState

@Composable
fun CustomMarkerMap() {
    val cameraPositionState = rememberCameraPositionState {
        position = CameraPosition.fromLatLngZoom(LatLng(39.9042, 116.4074), 12f)
    }
    val context = LocalContext.current

    GoogleMap(
        modifier = Modifier.fillMaxSize(),
        cameraPositionState = cameraPositionState
    ) {
        // 带自定义文本的红色标记
        val customMarkerIcon = createCustomMarkerWithText(
            context = context,
            baseMarkerResId = R.drawable.ic_red_marker, // 替换为你的基础标记图标
            text = "22222",
            textSize = 22f
        )

        Marker(
            state = MarkerState(position = LatLng(39.9042, 116.4074)),
            icon = customMarkerIcon,
            title = "hello",
            snippet = "World"
        )

        // 巴士内置图标标记
        Marker(
            state = MarkerState(position = LatLng(39.91, 116.41)),
            icon = BitmapDescriptorFactory.fromResource(R.drawable.ic_bus), // 替换为地图内置巴士图标资源
            title = "巴士站点"
        )
    }
}

3. 性能优化建议

  • 缓存BitmapDescriptor:若多个标记使用相同样式,缓存生成的BitmapDescriptor,避免重复创建Bitmap。
  • 适配屏幕密度:根据设备屏幕密度调整文本大小和图标尺寸,保证跨设备显示一致。
  • 复用绘图对象:在工具函数中复用Paint对象,减少内存开销。

内容的提问来源于stack exchange,提问作者Pawandeep Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 00:45:19