Android Google 使用动态图像映射集群项目标记 URL - 用所有标记覆盖 URL

Android Google map Cluster Item marker with dynamic image URL - overwrite URL with all marker

在我的地图上有集群的应用程序中,Top/Main 集群标记显示标记总数,点击显示所有子集群项目标记。

在集群项(子集群标记)中显示具有不同颜色的圆形背景,并且在显示来自 URL 的图像(从 Web 服务响应中获取)之间,集群项正确显示图像但是 我的问题是在刷新最后一个响应图像 URL 后用所有标记图像覆盖,意味着 所有集群项目显示相同的图像而不是不同的图像。

请任何人帮助解决这个覆盖问题。我的代码如下。

      private class RenderClusterInfoWindow extends DefaultClusterRenderer<ModelClusterBikeList> {

    private final IconGenerator mClusterIconGenerator = new IconGenerator(getActivity());
    private final IconGenerator iconGenerator = new IconGenerator(getActivity());
    ImageView imageView;
    int markerWidth;
    int markerHeight;
    private DisplayImageOptions options;

    RenderClusterInfoWindow(Activity context, GoogleMap map, ClusterManager<ModelClusterBikeList> clusterManager) {
        super(context, map, clusterManager);

        // Main inflate view it show number data available inside cluster
        View multiProfile = getLayoutInflater().inflate(R.layout.inflate_cluster, null);
        mClusterIconGenerator.setContentView(multiProfile);

        markerWidth = (int) context.getResources().getDimension(R.dimen.custom_profile_image);
        markerHeight = (int) context.getResources().getDimension(R.dimen.custom_profile_image);

        // inflator its show image from the response url. (cluster item)
        View clusterITEM = getLayoutInflater().inflate(R.layout.inflate_cluster_item, null);
        iconGenerator.setContentView(clusterITEM);
        imageView = clusterITEM.findViewById(R.id.imageClusterPIN);


        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(markerWidth, markerHeight);
        layoutParams.gravity = Gravity.CENTER;
        imageView.setLayoutParams(layoutParams);


        ImageLoader.getInstance().init(ImageLoaderConfiguration.createDefault(getActivity()));

        options = new DisplayImageOptions.Builder()
                .showImageForEmptyUri(R.mipmap.image_icn)
                .showImageOnFail(R.mipmap.image_icn)
                .cacheInMemory(false)
                .cacheOnDisk(true)
                .considerExifParams(true)
                .bitmapConfig(Bitmap.Config.RGB_565)
                .build();
    }

    @Override
    protected boolean shouldRenderAsCluster(Cluster<ModelClusterBikeList> cluster) {

        if (getActivity() != null) {
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (googleMap.getCameraPosition().zoom > 19.0) {
                        setClusterSize = 2;
                    } else {
                        setClusterSize = 4;
                    }
                }
            });
        }

        if (setClusterSize == 2) {
            return cluster.getSize() > cluster.getSize();
        } else {
            return cluster.getSize() > setClusterSize;
        }

    }

    @Override
    protected void onClusterRendered(Cluster<ModelClusterBikeList> cluster, Marker marker) {
        super.onClusterRendered(cluster, marker);
    }

    @Override
    protected void onBeforeClusterItemRendered(ModelClusterBikeList item, MarkerOptions markerOptions) {


        iconGenerator.setBackground(
                ContextCompat.getDrawable(getActivity(), R.drawable.round_asset));


        ImageLoader.getInstance().displayImage(item.getAssets_img_url(), imageView, options);

        // Issue is here , overwrite image url here with all marker./cluster item.
        Bitmap icon = iconGenerator.makeIcon(item.getAssets_img_url());
        markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));

        markerOptions.title(item.getId());
        markerOptions.draggable(true);

        super.onBeforeClusterItemRendered(item, markerOptions);
    }

    @Override
    protected void onBeforeClusterRendered(Cluster<ModelClusterBikeList> cluster, MarkerOptions markerOptions) {

        mClusterIconGenerator.setBackground(null);
        Bitmap icon = mClusterIconGenerator.makeIcon(String.valueOf(cluster.getSize()));
        markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));

    }

    @Override
    protected void onClusterItemRendered(ModelClusterBikeList clusterItem, Marker marker) {
        super.onClusterItemRendered(clusterItem, marker);
    }
}

我也尝试将 "onBeforeClusterItemRendered" 的所有代码放入 onClusterItemRendered 但得到相同的结果,相同的覆盖最后 url 包含所有杂乱项。

你好@Topsy 按照下面的方法更改代码,它会为你工作。

首先将 onBeforeClusterItemRendered 方法替换为以下代码。

   @Override
   protected void onBeforeClusterItemRendered(ModelClusterBikeList item, MarkerOptions 
   markerOptions) {

        icon = iconGenerator.makeIcon();
        markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon)).
                                                      title(item.getAssets_img_url());

        markerOptions.title(item.getId());
        markerOptions.draggable(true);

        super.onBeforeClusterItemRendered(item, markerOptions);
   }

然后将 onClusterItemRendered 方法替换为以下代码。

   @Override
   protected void onClusterItemRendered(ModelClusterBikeList clusterItem, Marker 
   marker) {


     if (getActivity() != null) {

         Glide.with(getActivity())
              .asBitmap()
              .load(clusterItem.getAssets_img_url())
              .error(R.drawable.ic_launcher)
              .diskCacheStrategy(DiskCacheStrategy.ALL)
              .into(new CustomTarget<Bitmap>() {
               @Override
               public void onResourceReady(@NonNull Bitmap resource, @Nullable 
               Transition<? super Bitmap> transition) {

                   try {
                      if (googleMap != null) {

                            iconGenerator.setBackground(
                            ContextCompat.getDrawable(getActivity(), 
                                                        R.drawable.round_asset));

                            imageView.setImageBitmap(resource);
                            imageView.buildDrawingCache();
                            Bitmap icon = iconGenerator.makeIcon();
                             if (icon != null) {
                             marker.setIcon(BitmapDescriptorFactory.fromBitmap(icon));
                           }
                         }
                     } catch (Exception e) {
                              e.printStackTrace();
                      }
                 }

                @Override
                public void onLoadCleared(@Nullable Drawable placeholder) {
                }
            });
          }

      }

这是一个使用 Kotlin、Coroutine 和 Coil 的更新解决方案:

class Custom(
    private val coroutineScope: CoroutineScope,
    private val context: Context,
    private val map: GoogleMap,
    clusterManager: ClusterManager<CustomMapItem>?,
) : DefaultClusterRenderer<CustomMapItem>(context, map, clusterManager), GoogleMap.OnCameraIdleListener {
    var itemId: String? = null
    private val iconFactory = IconGenerator(context)
    private var currentZoomLevel = 0f
    private var maxZoomLevel = 0f

    /**
     * Method called right after the cluster item (the marker) is rendered.
     * This is where properties for the Marker object should be set.
     */
    override fun onClusterItemRendered(clusterItem: CustomMapItem, marker: Marker) {
        super.onClusterItemRendered(clusterItem, marker)
        marker.tag = clusterItem
        coroutineScope.launch {
            val drawable: Drawable = checkNotNull(
                context.imageLoader.execute(
                    ImageRequest.Builder(context)
                        .data(clusterItem.item.imageUrl)
                        .fallback(R.drawable.ui_img_default_profile)
                        .error(R.drawable.ui_img_default_profile)
                        .diskCachePolicy(CachePolicy.ENABLED)
                        .allowHardware(false)
                        .build(),
                ).drawable,
            )
            val imageView = ImageView(context).apply {
                setImageDrawable(drawable)
                scaleType = ImageView.ScaleType.CENTER_CROP
                layoutParams = ViewGroup.LayoutParams(PROFILE_PICTURE_SIZE_IN_DP.toPxSize, PROFILE_PICTURE_SIZE_IN_DP.toPxSize)
            }
            iconFactory.setContentView(imageView)
            marker.setIcon(BitmapDescriptorFactory.fromBitmap(iconFactory.makeIcon()))
            if (clusterItem.item.id == itemId) {
                marker.showInfoWindow()
            }
        }
    }

    override fun onCameraIdle() {
        currentZoomLevel = map.cameraPosition.zoom
        maxZoomLevel = map.maxZoomLevel
    }

    override fun shouldRenderAsCluster(cluster: Cluster<CustomMapItem>): Boolean {
        // Detect overlapped ege case
        if (currentZoomLevel >= maxZoomLevel - 1 && cluster.size > 1) {
            var zIndex = 1
            for (item in cluster.items) {
                item.zIndex = zIndex++
            }
        }
        return currentZoomLevel < maxZoomLevel - 1 && cluster.size > 1
    }

    companion object {
        private const val PROFILE_PICTURE_SIZE_IN_DP = 48
    }
}