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

使用Glide在Google Map加载多自定义标记仅显示最后一个,如何解决?

解决Google Map中Glide加载多个自定义标记仅显示最后一个的问题

我帮你分析下这个问题,你遇到的情况其实很常见,主要是Glide异步加载的特性加上循环变量引用的坑导致的——因为Glide加载图片是异步操作,当图片加载完成的回调执行时,循环已经走完了,所有回调都引用了循环最后一次的成员数据,所以最后只有最后一个标记被正确设置并显示。另外,如果没有为每个标记创建独立的MarkerOptions或BitmapDescriptor实例,也会导致覆盖问题。

下面是具体的解决步骤和修改后的代码:

核心解决思路

  1. 让循环内的当前成员变量成为“有效不可变”的,确保Glide回调能捕获到当前循环的对象,而非最后一个。
  2. 为每个标记创建独立的MarkerOptions实例,避免后续设置覆盖之前的标记配置。
  3. 正确使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:21:16