Подтвердить что ты не робот

Маркер карты Google заменяется ограничивающим прямоугольником при масштабировании

Я использую SupportMapFragment внутри Fragment и последние Android Map Utils для кластеризации. После обновления сервисов Google Play до 9.0.83 маркеры единой карты Google заменяются ограничивающим прямоугольником при масштабировании. Изменены только одиночные маркеры, кластерные маркеры в порядке. Изменение параметра аппаратного ускорения в манифесте приложения ничего не меняет. Как это исправить?

введите описание изображения здесь

P.S.

compile 'com.google.android.gms:play-services-maps:8.4.0'
4b9b3361

Ответ 1

Я использую упрощенную версию обходного пути @bishop87 из проблемы в проекте github. Также добавлено кэширование для растровых изображений кластера, что сделало его намного более безопасным для OOM.

Если у вас нет средства рендеринга кластеров, используйте этот или переместите этот код самостоятельно:

SimpleClusterRenderer.java

public class SimpleClusterRenderer extends DefaultClusterRenderer<AuctionItem> {
    private static final int CLUSTER_PADDING = 12;
    private static final int ITEM_PADDING = 7;

    private final Bitmap mIconItemGreen;
    private final IconGenerator mIconClusterGenerator;
    private final float mDensity;

    public SimpleClusterRenderer(Context context, GoogleMap map, ClusterManager<AuctionItem> clusterManager) {
        super(context, map, clusterManager);

        mDensity = context.getResources().getDisplayMetrics().density;

        mIconClusterGenerator = new CachedIconGenerator(context);
        mIconClusterGenerator.setContentView(makeSquareTextView(context, CLUSTER_PADDING));
        mIconClusterGenerator.setTextAppearance(com.google.maps.android.R.style.ClusterIcon_TextAppearance);

        IconGenerator iconItemGenerator = new IconGenerator(context);
        iconItemGenerator.setContentView(makeSquareTextView(context, ITEM_PADDING));
        iconItemGenerator.setBackground(makeClusterBackground(ContextCompat.getColor(context, R.color.simple_green)));
        mIconItemGreen = iconItemGenerator.makeIcon();
    }

    @Override
    protected void onBeforeClusterItemRendered(AuctionItem item, MarkerOptions markerOptions) {
        markerOptions.icon(BitmapDescriptorFactory.fromBitmap(mIconItemGreen));
    }

    @Override
    protected void onBeforeClusterRendered(Cluster<AuctionItem> cluster, MarkerOptions markerOptions) {
        int clusterSize = getBucket(cluster);

        mIconClusterGenerator.setBackground(makeClusterBackground(getColor(clusterSize)));
        BitmapDescriptor descriptor = BitmapDescriptorFactory.fromBitmap(mIconClusterGenerator.makeIcon(getClusterText(clusterSize)));
        markerOptions.icon(descriptor);
    }

    @Override
    protected boolean shouldRenderAsCluster(Cluster<AuctionItem> cluster) {
        // Always render clusters.
        return cluster.getSize() > 1;
    }

    private int getColor(int clusterSize) {
        float size = Math.min((float) clusterSize, 300.0F);
        float hue = (300.0F - size) * (300.0F - size) / 90000.0F * 220.0F;
        return Color.HSVToColor(new float[]{hue, 1.0F, 0.6F});
    }

    private LayerDrawable makeClusterBackground(int color) {
        ShapeDrawable mColoredCircleBackground = new ShapeDrawable(new OvalShape());
        mColoredCircleBackground.getPaint().setColor(color);
        ShapeDrawable outline = new ShapeDrawable(new OvalShape());
        outline.getPaint().setColor(0x80ffffff);
        LayerDrawable background = new LayerDrawable(new Drawable[]{outline, mColoredCircleBackground});
        int strokeWidth = (int) (mDensity * 3.0F);
        background.setLayerInset(1, strokeWidth, strokeWidth, strokeWidth, strokeWidth);
        return background;
    }

    private SquareTextView makeSquareTextView(Context context, int padding) {
        SquareTextView squareTextView = new SquareTextView(context);
        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        squareTextView.setLayoutParams(layoutParams);
        squareTextView.setId(R.id.text);
        int paddingDpi = (int) (padding * mDensity);
        squareTextView.setPadding(paddingDpi, paddingDpi, paddingDpi, paddingDpi);
        return squareTextView;
    }
}

CachedIconGenerator.java

public class CachedIconGenerator extends IconGenerator {

    private final LruCache<String, Bitmap> mBitmapsCache;
    private String mText;

    public CachedIconGenerator(Context context) {
        super(context);

        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);

        // Use 1/8th of the available memory for this memory cache.
        final int cacheSize = maxMemory / 8;
        mBitmapsCache = new LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                // The cache size will be measured in kilobytes rather than
                // number of items.
                return bitmap.getByteCount() / 1024;
            }
        };
    }

    public Bitmap makeIcon(String text) {
        mText = text;
        return super.makeIcon(text);
    }

    @Override
    public Bitmap makeIcon() {
        if (TextUtils.isEmpty(mText)) {
            return super.makeIcon();
        } else {
            Bitmap bitmap = mBitmapsCache.get(mText);
            if (bitmap == null) {
                bitmap = super.makeIcon();
                mBitmapsCache.put(mText, bitmap);
            }
            return bitmap;
        }
    }
}

P.S. Вам также нужно заменить R.color.simple_green цветом булавки, который вы хотите.

P.P.S. Забыл упомянуть, что этот подход имеет незначительное влияние на производительность. Поэтому было бы лучше обновить это решение с помощью разных подходов к Play Services 9.0.83 и другим, если Google исправит эту проблему в следующем выпуске приложений для Служб.

Ответ 2

В соответствии с tyczj это произошло, когда службы Google Play (собственные файлы) обновлены до 9.0.x.

Из взглядов на обсуждение проблемы Github обходной путь заключается в следующем:

Возможный рабочий стол на странице gmaps-api-issues:

изменить marker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.drawableid));

в marker.setIcon(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(GetResources(), R.drawable.drawableid)));//может повлиять на потребление общей памяти tho (?), я не тестировал больше, чем приложение, о котором сообщалось в проблема.

Также отмечая:

Я могу подтвердить эту проблему. В дополнение к @Mavamaarten вы не должны повторное использование изображений маркеров.

(Источник: https://github.com/googlemaps/android-maps-utils/issues/276)

Ответ 3

Для меня проблема возникает, когда: (1) я удаляю маркер с помощью пользовательского значка или (2) устанавливаю новый значок после создания...

Чтобы решить первый случай, вам нужно установить значок по умолчанию перед удалением...

if (marker != null) {
    marker.setIcon(BitmapDescriptorFactory.defaultMarker());
    marker.remove();
}

Чтобы решить второй случай, вам нужно добавить копию маркера с новым пользовательским значком, а затем удалить в том же первом случае...

Пока команда Google Maps не устранит эту проблему, это решение...

Удачи...