Android Google Map自定义Marker加载网络图片不显示问题求助
Android Google Map自定义Marker网络图片不显示问题排查与解决
问题核心原因
- Glide异步加载时机不匹配:Glide加载网络图片是异步任务,调用
into(markerImage)后不会立刻完成图片渲染,但你紧接着就生成了Marker的Bitmap,此时ImageView中还是占位图(R.drawable.ic_user)或空白,导致网络图片无法显示。 - 循环索引越界:代码中
for(i in 0..arraylist?.size)会遍历到arraylist.size这个无效索引,数组最大有效索引是size-1,会直接抛出IndexOutOfBoundsException。 - 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
相关产品推荐
相关产品推荐

