问题
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 by bounding rectangle on zoom. Only single markers are replaced, cluster markers are fine. Changing hardware acceleration parameter in app manifest doesn't change anything. How to fix it?
P.S.
compile 'com.google.android.gms:play-services-maps:8.4.0'
回答1:
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.
回答2:
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)
回答3:
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...
来源:https://stackoverflow.com/questions/37211274/google-map-marker-is-replaced-by-bounding-rectangle-on-zoom