Google map marker is replaced by bounding rectangle on zoom

后端 未结 3 478
长发绾君心
长发绾君心 2020-12-15 08:37

I\'m using SupportMapFragment inside Fragment and recent Android Map Utils for clustering. After Google Play Services update to 9.0.83 google single map markers are replaced

相关标签:
3条回答
  • 2020-12-15 08:53

    For me the problem happens when: (1) I remove a marker with a custom icon or (2) set a new icon after create...

    To solve the first case, you need to set the default icon before remove...

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

    To solve the second case, you need to add a copy of the marker with the new custom icon and later remove in the same first case ...

    Until Google Maps Team fix this problem it is a solution...

    Good luck...

    0 讨论(0)
  • 2020-12-15 09:06

    As per tyczj, this started happening when Google Play services (the proprietary binaries) updated to 9.0.x.

    From the looks of the Github issue discussion, the workaround is to:

    Possible workarround from the gmaps-api-issues page:

    change marker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.drawableid));

    to marker.setIcon(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.drawableid))); //could affect general memory consumption tho(?), I haven't tested with more than the app reported with in the issue.

    Also noting:

    I can confirm this issue. In addition to @Mavamaarten you must not reuse marker images.

    (Source: https://github.com/googlemaps/android-maps-utils/issues/276)

    0 讨论(0)
  • 2020-12-15 09:10

    I use simplified version of @bishop87's workaround from issue on github project. Also added caching for cluster bitmaps, which made it much more OOM-safer.

    If you don't have Cluster renderer than use this one or move this code to your own:

    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. You also need to replace R.color.simple_green with pin colour you want.

    P.P.S. Forgot to mention, that this approach has negligible performance impact. So it would be better to update this solution with different approaches for Play Services 9.0.83 and others, if Google will fix this issue on next Play Services app release.

    0 讨论(0)
提交回复
热议问题