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

Android GoogleMap Compose自定义Marker图标:URL加载实现方案

GoogleMap Compose 自定义Marker图标:从URL加载并处理Bitmap

GoogleMap Compose支持为Marker设置自定义图标,但原生并未提供从URL直接加载图标的功能。以下是一套完整的实现方案,包含从URL加载Bitmap、缩放处理、圆角处理,最终将处理后的图片设置为Marker图标,同时也欢迎分享更简洁的实现思路。


GoogleMap Compose 核心实现代码

val bitmapState = remember {
    mutableStateOf<BitmapDescriptor?>(null)
}
LaunchedEffect(key1 = locationFocus.value.imageUrl) {
    getBitmapFromURL(locationFocus.value.imageUrl)?.let { bm ->
        getResizedBitmap(bm, 150, 150)?.let { resizedBm ->
            getRoundedCornerBitmap(resizedBm)?.let { roundedBm ->
                bitmapState.value = BitmapDescriptorFactory.fromBitmap(roundedBm)
            }
        }
    }
}

Marker(
    state = MarkerState(position = cameraPositionState.position.target),
    title = locationFocus.value.name,
    snippet = locationFocus.value.address,
    icon = bitmapState.value,
)

工具函数实现

1. 从URL加载Bitmap

suspend fun getBitmapFromURL(imgUrl: String?): Bitmap? =
    withContext(Dispatchers.IO) {
        try {
            val url = URL(imgUrl)
            val connection: HttpURLConnection = url.openConnection() as HttpURLConnection
            connection.doInput = true
            connection.connect()
            val input: InputStream = connection.inputStream
            BitmapFactory.decodeStream(input)
        } catch (e: IOException) {
            // 此处可添加日志打印
            null
        }
    }

2. 缩放Bitmap

fun getResizedBitmap(bm: Bitmap, newWidth: Int, newHeight: Int): Bitmap? {
    val width = bm.width
    val height = bm.height
    val scaleWidth = newWidth.toFloat() / width
    val scaleHeight = newHeight.toFloat() / height
    // 计算缩放矩阵
    val matrix = Matrix()
    matrix.postScale(scaleWidth, scaleHeight)
    // 生成缩放后的Bitmap
    val resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false)
    bm.recycle()
    return resizedBitmap
}

3. 生成圆角Bitmap

fun getRoundedCornerBitmap(bitmap: Bitmap): Bitmap? {
    val output = Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)
    val canvas = Canvas(output)
    val color = Color.BLACK
    val paint = Paint()
    val rect = Rect(0, 0, bitmap.width, bitmap.height)
    val rectF = RectF(rect)
    val roundPx = 16f // 圆角半径,可根据需求调整

    paint.isAntiAlias = true
    canvas.drawARGB(0, 0, 0, 0)
    paint.color = color
    canvas.drawRoundRect(rectF, roundPx, roundPx, paint)

    paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
    canvas.drawBitmap(bitmap, rect, rect, paint)

    bitmap.recycle()
    return output
}

若有更简洁的代码实现,欢迎留言分享。感谢支持

内容的提问来源于stack exchange,提问作者Ho Binh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 00:35:20