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

Android Google Map自定义Marker加载网络图片不显示问题求助

Android Google Map自定义Marker网络图片不显示问题排查与解决

问题核心原因

  1. Glide异步加载时机不匹配:Glide加载网络图片是异步任务,调用into(markerImage)后不会立刻完成图片渲染,但你紧接着就生成了Marker的Bitmap,此时ImageView中还是占位图(R.drawable.ic_user)或空白,导致网络图片无法显示。
  2. 循环索引越界:代码中for(i in 0..arraylist?.size)会遍历到arraylist.size这个无效索引,数组最大有效索引是size-1,会直接抛出IndexOutOfBoundsException。
  3. View测量逻辑错误:用屏幕宽高来measure自定义Marker的View,会导致View尺寸异常,进一步掩盖图片显示问题。

解决方案

推荐方案:Glide异步加载回调,图片就绪后生成Marker

这种方式不会阻塞主线程,适配异步加载特性:

override fun onMapReady(googleMap: GoogleMap?) {
    mMap = googleMap ?: return
    // 地图基础配置
    mMap.apply {
        animateCamera(CameraUpdateFactory.zoomTo(16.0f))
        mapType = GoogleMap.MAP_TYPE_NORMAL
        setMinZoomPreference(6.0f)
        setMaxZoomPreference(21.0f)
        isIndoorEnabled = false
        isMyLocationEnabled = true
    }

    val coordinate = LatLng(
        prefs?.current_lati?.toDouble()!!,
        prefs?.current_longi?.toDouble()!!
    )
    val location = CameraUpdateFactory.newLatLngZoom(coordinate, 15f)

    // 修正循环边界:用until避免越界
    arraylist?.let { list ->
        for (i in 0 until list.size) {
            val item = list[i]
            val lat = item.latitude ?: continue
            val longi = item.longitude ?: continue
            val position = LatLng(lat, longi)

            // 异步加载图片,完成后生成Marker
            Glide.with(requireContext())
                .asBitmap()
                .load(item.image)
                .placeholder(R.drawable.ic_user)
                .error(R.drawable.ic_user)
                .into(object : CustomTarget<Bitmap>() {
                    override fun onResourceReady(
                        resource: Bitmap,
                        transition: Transition<in Bitmap>?
                    ) {
                        val markerBitmap = createCustomMarker(requireContext(), resource)
                        mMap.addMarker(
                            MarkerOptions()
                                .position(position)
                                .icon(BitmapDescriptorFactory.fromBitmap(markerBitmap))
                        )
                    }

                    override fun onLoadCleared(placeholder: Drawable?) {}
                })
        }
    }

    mMap.moveCamera(location)
    mMap.animateCamera(location)
}

private fun createCustomMarker(context: Context, userBitmap: Bitmap): Bitmap {
    val marker = LayoutInflater.from(context).inflate(R.layout.lay_cutom_marker, null)
    val markerImage: ImageView = marker.findViewById(R.id.img_res)
    markerImage.setImageBitmap(userBitmap)

    // 正确测量View:指定固定宽度,高度自适应
    marker.measure(
        View.MeasureSpec.makeMeasureSpec(52, View.MeasureSpec.EXACTLY),
        View.MeasureSpec.makeMeasureSpec(ViewGroup.LayoutParams.WRAP_CONTENT, View.MeasureSpec.UNSPECIFIED)
    )
    marker.layout(0, 0, marker.measuredWidth, marker.measuredHeight)

    marker.buildDrawingCache()
    return Bitmap.createBitmap(
        marker.measuredWidth,
        marker.measuredHeight,
        Bitmap.Config.ARGB_8888
    ).apply {
        val canvas = Canvas(this)
        marker.draw(canvas)
    }
}

备选方案:同步加载图片(不推荐,需注意线程)

如果场景简单,可在子线程中同步加载图片,避免阻塞主线程:

// 在子线程处理标记添加
lifecycleScope.launch(Dispatchers.IO) {
    arraylist?.let { list ->
        for (i in 0 until list.size) {
            val item = list[i]
            val lat = item.latitude ?: continue
            val longi = item.longitude ?: continue
            val position = LatLng(lat, longi)

            // 同步获取图片,异常时用占位图
            val bitmap = try {
                Glide.with(requireContext())
                    .asBitmap()
                    .load(item.image)
                    .submit()
                    .get()
            } catch (e: Exception) {
                BitmapFactory.decodeResource(context.resources, R.drawable.ic_user)
            }

            val markerBitmap = createCustomMarker(requireContext(), bitmap)
            // 切回主线程添加Marker
            withContext(Dispatchers.Main) {
                mMap.addMarker(
                    MarkerOptions()
                        .position(position)
                        .icon(BitmapDescriptorFactory.fromBitmap(markerBitmap))
                )
            }
        }
    }
}

额外检查项

  • 确认AndroidManifest.xml已添加网络权限:<uses-permission android:name="android.permission.INTERNET" />
  • 验证图片URL是否有效,不存在404或访问权限问题
  • 确保Glide依赖配置正确(Glide4+版本需对应依赖)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 12:45:46