android - 来自图像 URL GoogleMap API V2 的自定义标记图标

标签 android google-maps android-activity google-maps-markers picasso

我有一个问题。

我的目标是加载公司的自定义图像并显示它而不是默认标记图标。

但是我遇到了这个问题。

仅当我关闭并再次打开 Activity 时才会显示图标。

这是我在 map 上添加标记的代码。

private void addMarkerToTheMap(GoogleMapInfoBundle infoBundle) {
        if (infoBundle.placeMarker) {
            LatLng latLng = new LatLng(infoBundle.company.getLatitude(), infoBundle.firm.getLongitude());
            MarkerOptions markerOptions = new MarkerOptions()
                    .title(infoBundle.company.getName())
                    .snippet(infoBundle.company.getAddress())
                    .position(latLng);
            Marker marker = mGoogleMap.addMarker(markerOptions);
            try {
                Picasso.with(this).load(NetworkUtils.getUrlOfScaledImage(infoBundle.company.getLogo(), DEFAULT_ICON_SCALE_PERCENTAGE)).into(new PicassoMarker(marker));
            } catch (IllegalArgumentException ignore) {
                // Do nothing
            }
        }

PicassoMarker

public class PicassoMarker implements Target {
    Marker mMarker;

    public PicassoMarker(Marker marker) {
        mMarker = marker;
    }

    @Override
    public int hashCode() {
        return mMarker.hashCode();
    }

    @Override
    public boolean equals(Object o) {
        if (o instanceof PicassoMarker) {
            Marker marker = ((PicassoMarker) o).mMarker;
            return mMarker.equals(marker);
        } else {
            return false;
        }
    }

    @Override
    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
        mMarker.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap));
    }

    @Override
    public void onBitmapFailed(Drawable errorDrawable) {
    }

    @Override
    public void onPrepareLoad(Drawable placeHolderDrawable) {

    }
}

在这种情况下,它显示默认图标 enter image description here .

我试过用另一种方式来制作它

MarkerOptions markerOptions = new MarkerOptions()
                        .title(infoBundle.company.getName())
                        .snippet(infoBundle.company.getAddress())
                        .position(latLng);
  try {
                Picasso.with(this).load(NetworkUtils.getUrlOfScaledImage(infoBundle.company.getLogo(), DEFAULT_ICON_SCALE_PERCENTAGE)).into(new PicassoMarker(mGoogleMap, markerOptions));
            } catch (IllegalArgumentException ignore) {
                // Do nothing
            }

并在图像下载完成后在回调中向 map 添加标记。

   @Override
    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
        mMarkerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmap));
        mGoogleMap.addMarker(mMarkerOptions);
    }

在这种情况下它不显示任何标记。

但在这两种情况下,如果我关闭 Activity 并再次打开它,所有内容都将正确显示并带有图标。

我不知道什么会导致这样的问题。似乎 GoogleMap 缓存图标图像或其他东西。

我有一点使用 GoogleMaps API 的经验,也许我遗漏了什么。

希望有人能帮忙。

谢谢。

最佳答案

问题不在 GoogleMapSupportMapFragment 中,而是在 Picasso 中,不完全是在 Picasso 中,而是在我的流程。

使用自定义 Target 类时,您应该始终记住的一点是,在内部 Picasso 使用 WeakReference 来存储 Target对象,因此如果您直接在 Picasso 调用中创建新的 Target,它将被垃圾收集器销毁。

Picasso 提供了 Callback 类,因此您可以创建匿名类,并且您的类将持有引用。

但有一件事是我缺少 Callback 类,它提供 Bitmap 作为响应,例如 Target(但目标主要由自定义 View 使用).

所以我找到了这样的解决方案,它很丑陋,但就在这里。

我已经创建了专门的列表来存储目标对象,不被丢弃。

  Marker marker = mGoogleMap.addMarker(markerOptions);
            mMarkerCompanyMap.put(marker, infoBundle.firm);
            try {
                PicassoMarkerTarget markerTarget = new PicassoMarkerTarget(marker, mImageLoadingCallback);
                mPicassoMarkerTargetList.add(markerTarget);
                Picasso.with(this)
                        .load(NetworkUtils.getUrlOfScaledImage(infoBundle.firm.getLogo(), DEFAULT_ICON_SCALE_PERCENTAGE))
                        .into(markerTarget);
            } catch (IllegalArgumentException ignore) {
                // Do nothing
            }

我正在传递 mImageLoadingCallback 以从 Target
回调回 Activity 它看起来像。

private Callback mImageLoadingCallback = new Callback() {
        @Override
        public void onSuccess() {
            Logger.logError("IMAGE LOADED IN CALLBACK " + mPendingImagesCount);
            if (mPendingImagesCount <= 0) {
                mPicassoMarkerTargetList.clear();
            } else {
                mPendingImagesCount--;
            }
        }

        @Override
        public void onError() {
            // You may start laughing, but just for the sake of not duplicating code
            onSuccess();
        }
    };

此回调可用于其他目的,但现在仅用于清除数组。

当然还有 PicassoMarkerTarget

   @Override
    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
        mMarker.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap));
        mDownloadListenerCallback.onSuccess();
        Logger.logError("IMAGE LOADED IN PICASSO MARKER TARGET");
    }

这是一个丑陋的解决方案,但也许这个回调在未来会有帮助。

拜托,如果您有更好的解决方案的想法 - 请分享。 谢谢。

关于android - 来自图像 URL GoogleMap API V2 的自定义标记图标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35537546/

相关文章:

google-maps - 什么是在 v3 javascript 中替换 google maps api v2 javascript 的 getLocation() 函数?

android - 在 ListView 中更改 TextView 的文本时出现问题

android - 如何在 Android 中创建如图所示的弹出窗口?

android - 字段需要 API 级别 29(当前最小值为 16): android. app.TaskInfo#topActivity

android - 在某些 Android 设备上握手失败

google-maps - 如何使用谷歌地图查询字符串放置标记

javascript - 给定一个点和一个距离,计算 map 上的一个点

java - 在 OnPostExecute() 中使用 StartActivity

android - 将点击监听器添加到标题栏图像

android - 附近的 Google Play 服务注册失败,有 TOO_MANY_PENDING_INTENTS 个