Google Maps标记首次点击时Glide加载的图片不显示该如何解决
问题根因
- Google Maps 自定义InfoWindow本质是静态视图快照,
getInfoContents返回View后系统会直接将其渲染为位图显示,不会监听后续View的内容变更 - 首次点击标记时,Glide请求刚发起就返回了Window视图,此时生成的快照自然没有图片内容
- 如果你使用了全局复用的
window成员变量,首次点击发起的Glide请求会被第二次点击标记时的新请求覆盖,导致首次请求的回调完全不会触发 - 部分场景下如果你的InfoWindow中的ImageView没有设置固定宽高,Glide会因为无法测量视图尺寸导致请求挂起,不会触发加载回调
修复方案
核心修复代码
每次调用getInfoContents时重新inflate视图、给ImageView设置固定宽高,并在图片加载完成后直接刷新InfoWindow即可:
override fun getInfoContents(marker: Marker): View? { val pointOfInterest = marker.tag as? PointOfInterest ?: return null // 每次调用都重新inflate视图,避免复用全局View导致的请求覆盖问题 val window = LayoutInflater.from(context).inflate(R.layout.你的info_window布局文件名, null) window.findViewById<TextView>(R.id.marker_title).text = pointOfInterest.title val image = window.findViewById<ImageView>(R.id.marker_image) // 预先设置占位图,避免加载过程中空白 image.setImageResource(R.drawable.你的占位图资源名) Glide .with(context) .load(pointOfInterest.imageUrl) // 绑定当前图片的url作为签名,避免缓存复用异常 .signature(ObjectKey(pointOfInterest.imageUrl)) // 可选:如果你的ImageView没有固定宽高,手动指定加载尺寸 // .override(100.dpToPx(), 100.dpToPx()) .addListener(object : RequestListener<Drawable>{ override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean { Log.d("glide","Error loading the image url") return false } override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean { Log.d("glide","Loaded") // 图片加载完成后如果当前标记的InfoWindow正在展示,立刻刷新快照 if (marker.isInfoWindowShown) { marker.hideInfoWindow() marker.showInfoWindow() } return false } }) .into(image) return window }
注意:传入Glide的
context请使用当前活跃的Activity/Fragment实例,不要使用Application上下文,避免Glide因生命周期管控暂停请求。
可选优化
如果你的POI点数量较少,可以在添加标记到地图时就提前预加载图片,点击时直接读取缓存无需等待:
// 添加标记时执行预加载逻辑 Glide.with(context) .load(poi.imageUrl) .preload()
内容的提问来源于stack exchange,提问作者albertbuigues
相关产品推荐
相关产品推荐

