Android Google 地图显示自定义标记和聚类问题

Android Google map show custom marker and clustering issue

我想显示自定义标记以 google 映射和聚类它们。该标记包含一个 ImageView,它将显示从网络下载的头像。这是我的目标:

一切正常,但是,当我实施 Google Maps Android Marker Clustering Utility 时,ImageView 显示相同的头像(有时是两个错误的头像)。
这是我的自定义 MarkerRender:

public class MarkerRender extends DefaultClusterRenderer<Image> {
    private static final String TAG = MarkerRender.class.getSimpleName();
    private IconGenerator clusterGenerator;
    private IconGenerator markerGenerator;
    private ImageView mImgMarkerThumbnail;
    private ImageView mImgMarkerClusterThumbnail;
    private TextView txtSizeCluster;
    private Activity activity;
    private Bitmap mask, background;
    private AtomicInteger imageDownloadCounter;
    private int totalItem;
    private ImageSize imageSize;

    public MarkerRender(FragmentActivity activity, GoogleMap mMap, ClusterManager<Image> mClusterManager) {
        super(activity, mMap, mClusterManager);
        this.activity = activity;
        imageDownloadCounter = new AtomicInteger(0);
        mask = BitmapFactory.decodeResource(activity.getResources(),
                R.drawable.annotation_behind);
        background = BitmapFactory.decodeResource(activity.getResources(),
                R.drawable.annotation_behind);
        setUpClusterIcon();
        setUpMarker();
    }

    private void setUpClusterIcon() {
        clusterGenerator = new IconGenerator(activity);
        View clusterView = activity.getLayoutInflater().inflate(R.layout.custom_marker_cluster, null);
        txtSizeCluster = (TextView) clusterView.findViewById(R.id.tv_number_marker);
        mImgMarkerClusterThumbnail = (ImageView) clusterView.findViewById(R.id.img_load);
        clusterGenerator.setContentView(clusterView);
        clusterGenerator.setBackground(null);
    }

    private void setUpMarker() {
        markerGenerator = new IconGenerator(activity);
        View markerView = activity.getLayoutInflater().inflate(R.layout.custom_marker, null);
        mImgMarkerThumbnail = (ImageView) markerView.findViewById(R.id.img_load);
        markerGenerator.setContentView(markerView);
        markerGenerator.setBackground(null);

    }

    @Override
    protected void onBeforeClusterItemRendered(final Image image, final MarkerOptions markerOptions) {
        initImageSizeIfNeed();
        Bitmap icon = markerGenerator.makeIcon();
        PFLogManager.INSTANCE.logE(TAG, "maken icon: " + icon.hashCode());
        markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
        icon.recycle();
    }

    @Override
    protected void onClusterItemRendered(final Image image, Marker marker) {
        super.onClusterItemRendered(image, marker);
        ImageLoader.getInstance().loadImage(image.getMapImageLink(), imageSize,
                new SimpleImageLoadingListener() {
                    @Override
                    public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                        Bitmap croppedBitmap = Helpers.makeCroppedBitmap(loadedImage, background, mask);
                        mImgMarkerThumbnail.setImageBitmap(croppedBitmap);
                    }
                });
    }

    @Override
    protected void onBeforeClusterRendered(Cluster<Image> cluster, MarkerOptions markerOptions) {
        initImageSizeIfNeed();
        Bitmap icon = clusterGenerator.makeIcon();
        markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
        icon.recycle();
    }

    @Override
    protected void onClusterRendered(Cluster<Image> cluster, Marker marker) {
        super.onClusterRendered(cluster, marker);
        ArrayList<Image> list = new ArrayList<>(cluster.getItems());
        setTextNumberMarker(cluster);
        String urlFirstImage = list.get(0).getMapImageLink();
        ImageLoader.getInstance().loadImage(urlFirstImage, imageSize,
                new SimpleImageLoadingListener() {
                    @Override
                    public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                        final Bitmap croppedBitmap = Helpers.makeCroppedBitmap(loadedImage, background, mask);
                        mImgMarkerClusterThumbnail.setImageBitmap(croppedBitmap);
                    }
                });
    }

    private void loadClusterThumbnail(String url) {
    }

    private void setTextNumberMarker(Cluster<Image> cluster) {
        int size = cluster.getSize();
        if (size > 99) {
            txtSizeCluster.setText("99+");
        } else {
            txtSizeCluster.setText(String.valueOf(cluster.getSize()));
        }
    }

    @Override
    protected boolean shouldRenderAsCluster(Cluster cluster) {
        return cluster.getSize() > 1;
    }
}

我猜问题是我只使用一个 ImageView 来显示这些头像,所以我尝试为每个标记使用唯一的 ImageView(通过从 [=29 中扩充新的标记) =] 每次都需要),但结果是它们都显示空白标记(只有背景,没有头像)。

我自己解决了。我的解决方案是在从网络下载或从缓存中获取图像后使用 Marker.setIcon() 方法。我不再使用 ImageView 了。
所以,我修改了上面的MarkerRender class:
setUpClusterIcon()方法:

private void setUpClusterIcon() {
    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(markerWidth, markerHeight);
    ImageView marker = new ImageView(activity);
    marker.setLayoutParams(params);

    clusterGenerator = new IconGenerator(activity);
    clusterGenerator.setContentView(marker);
    clusterGenerator.setBackground(null);
}


onClusterItemRendered()方法:

 protected void onClusterItemRendered(final Image image, final Marker marker) {
        super.onClusterItemRendered(image, marker);
        ImageLoader.getInstance().loadImage(image.getMapImageLink(), imageSize,
                new SimpleImageLoadingListener() {
                    @Override
                    public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                        Bitmap croppedBitmap = Helpers.makeClusterItemBitmap(background, loadedImage, mask);
                        try {
                            marker.setIcon(BitmapDescriptorFactory.fromBitmap(croppedBitmap));
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });
    }


还有 makeClusterItemBitmap 辅助方法:

   public static Bitmap makeClusterItemBitmap(Bitmap background, Bitmap original, Bitmap mask) {
        Bitmap croppedOriginal = makeCroppedBitmap(original, mask);
        Bitmap result = Bitmap.createBitmap(background.getWidth(), background.getHeight(),
                Bitmap.Config.ARGB_8888);
        Canvas mCanvas = new Canvas(result);
        croppedOriginal = Bitmap.createScaledBitmap(croppedOriginal, croppedOriginal.getWidth() - 20, croppedOriginal.getHeight() - 20, true);
        mCanvas.drawBitmap(background, 0, 0, null);
        mCanvas.drawBitmap(croppedOriginal, 10, 10, null);
        return result;
    }

    public static Bitmap makeCroppedBitmap(Bitmap original, Bitmap mask) {
        original = Bitmap.createScaledBitmap(original, mask.getWidth(),
                mask.getHeight(), true);
        Bitmap result = Bitmap.createBitmap(original.getWidth(), original.getHeight(),
                Bitmap.Config.ARGB_8888);
        Canvas mCanvas = new Canvas(result);
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        mCanvas.drawBitmap(original, 0, 0, null);
        mCanvas.drawBitmap(mask, 0, 0, paint);
        paint.setXfermode(null);
        return result;
    }


完成,完成三天的噩梦研究日:P
但是,这种方法会导致新问题:the performance。由于绘制了很多层的新位图,地图有点滞后。我正在考虑改进这个:)
任何建议都适用 :D