Android Google map показывает нестандартный маркер и проблему с кластеризацией

Я хотел бы показать пользовательский маркер на карте Google и кластеризовать их. Маркер содержит ImageView будет показан аватар, загруженный из сети. Вот моя цель:
введите описание изображения здесь

Все в порядке, однако, когда я внедрил Утилиту Маркерной кластеризации Google Maps Android, 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 для каждого маркера (путем раздувания нового из xml каждый раз, когда это необходимо), но в результате они все показывают пустой маркер (только фон и отсутствует аватар).

1 ответ

Решение

Я решил это сам. Мое решение - использовать Marker.setIcon() метод после того, как изображение загружено из netword или получено из кэша. Я больше не использую ImageView.
Итак, я изменил выше MarkerRender учебный класс:
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

Другие вопросы по тегам