使用Glide在Google Map加载多自定义标记仅显示最后一个,如何解决?
解决Google Map中Glide加载多个自定义标记仅显示最后一个的问题
我帮你分析下这个问题,你遇到的情况其实很常见,主要是Glide异步加载的特性加上循环变量引用的坑导致的——因为Glide加载图片是异步操作,当图片加载完成的回调执行时,循环已经走完了,所有回调都引用了循环最后一次的成员数据,所以最后只有最后一个标记被正确设置并显示。另外,如果没有为每个标记创建独立的MarkerOptions或BitmapDescriptor实例,也会导致覆盖问题。
下面是具体的解决步骤和修改后的代码:
核心解决思路
- 让循环内的当前成员变量成为“有效不可变”的,确保Glide回调能捕获到当前循环的对象,而非最后一个。
- 为每个标记创建独立的
MarkerOptions实例,避免后续设置覆盖之前的标记配置。 - 正确使用Glide的
CustomTarget来获取Bitmap,确保每个标记的图片加载完成后独立生成图标并添加到地图。
修改后的代码示例
private void getZoom(List<Member> memberdata) { try { mMap.clear(); for (int i = 0; i < memberdata.size(); i++) { // 用final变量保存当前循环的Member对象,避免异步回调引用到最后一个循环的实例 final Member currentMember = memberdata.get(i); final String memberName = currentMember.getMemberName(); // 替换成你实际的成员名称get方法 final double lat = currentMember.getLatitude(); // 替换成你实际的纬度get方法 final double lng = currentMember.getLongitude(); // 替换成你实际的经度get方法 final String imageUrl = currentMember.getImageUrl(); // 替换成你实际的图片URL get方法 // 使用Glide加载Bitmap格式的图片,适配Google Map的Marker图标需求 Glide.with(this) .asBitmap() .load(imageUrl) .into(new CustomTarget<Bitmap>() { @Override public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) { // 可选:把图片裁剪成圆形(如果你的标记需要圆形头像) Bitmap circularBitmap = getCircularBitmap(resource); // 生成Marker需要的BitmapDescriptor BitmapDescriptor markerIcon = BitmapDescriptorFactory.fromBitmap( circularBitmap != null ? circularBitmap : resource ); // 为当前标记创建独立的MarkerOptions配置 MarkerOptions markerOptions = new MarkerOptions() .position(new LatLng(lat, lng)) .title(memberName) .icon(markerIcon); // 将标记添加到地图上 mMap.addMarker(markerOptions); } @Override public void onLoadCleared(@Nullable Drawable placeholder) { // 可选:在这里做一些内存清理操作,比如回收Bitmap } }); } } catch (Exception e) { e.printStackTrace(); } } // 可选工具方法:将Bitmap裁剪成圆形,适配头像类标记需求 private Bitmap getCircularBitmap(Bitmap bitmap) { Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(output); final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); final RectF rectF = new RectF(rect); paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); canvas.drawOval(rectF, paint); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); bitmap.recycle(); return output; }
额外注意事项
- 如果你用的是Glide 4.x版本,一定要用
CustomTarget而不是已过时的SimpleTarget,避免潜在的内存泄漏。 - 确保你的AndroidManifest.xml中添加了网络权限:
<uses-permission android:name="android.permission.INTERNET"/>,否则Glide无法加载网络图片。 - 如果图片加载慢或者有内存顾虑,可以给Glide添加占位图、错误图,或者设置图片压缩,比如
.override(100,100)来限制图片大小。
内容的提问来源于stack exchange,提问作者syam
相关产品推荐
相关产品推荐

