2016-05-13 10 views
13

Sto utilizzando SupportMapFragment all'interno di Fragment e il recente Android Map Utils per il clustering. Dopo l'aggiornamento di Google Play Services alla versione 9.0.83, gli indicatori di mappa singola google vengono sostituiti dal rettangolo di delimitazione sullo zoom. Vengono sostituiti solo i singoli marcatori, i marcatori di gruppo vanno bene. La modifica del parametro di accelerazione hardware nel manifest dell'app non cambia nulla. Come sistemarlo?L'indicatore di Google map viene sostituito dal rettangolo di delimitazione sullo zoom

enter image description here

P.S.

+2

sembra un file a qualcuno un bug report circa la IS Sue https://github.com/googlemaps/android-maps-utils/issues/276 – tyczj

risposta

5

Come per tyczj, questo ha iniziato a verificarsi quando i servizi di Google Play (i file binari proprietari) sono stati aggiornati alla 9.0.x.

Dagli sguardi di discussione problema Github, la soluzione è:

Possibile workarround dalla pagina GMaps-API-temi:

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

a marker.setIcon (BitmapDescriptorFactory.fromBitmap (BitmapFactory.decodeResource (getResources(), R.drawable.drawableid))); // potrebbe influire sul consumo di memoria generale tho (?), non ho testato con più rispetto all'app segnalata nel problema .

notando anche:

posso confermare questo problema. Oltre a @Mavamaarten non è necessario utilizzare le immagini dei marker di riutilizzo .

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

+0

Che cosa significa quell'ultima parte. "non devi riutilizzare le immagini dei marker" ?? –

+1

Fondamentalmente, la soluzione è sempre caricare nuove istanze bitmap ... invece di condividere lo stesso. –

+0

Sto condividendo lo stesso e non ottengo il bug. È normale? –

7

Io uso la versione semplificata del @ di bishop87 soluzione from issue on github project. Inoltre è stata aggiunta la memorizzazione nella cache per le bitmap del cluster, il che ha reso molto più OOM più sicuro.

Se non si dispone di renderer cluster di utilizzare questo o spostare questo codice al tuo:

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; 
     } 
    } 
} 

PS È inoltre necessario sostituire R.color.simple_green con il colore del pin desiderato.

P.P.S. Ho dimenticato di dire che questo approccio ha un impatto trascurabile sulle prestazioni. Pertanto, sarebbe meglio aggiornare questa soluzione con approcci diversi per Play Services 9.0.83 e altri, se Google risolverà questo problema nella prossima versione dell'app Play Services.

+1

Creazione di propri BitmapDescriptor per ogni elemento può causare OutOfMemoryException o simile su alcuni dispositivi. Come ho capito, perché la libreria di cluster mostra tutti i punti prima di ricalcolare una versione cluster. – tse

+0

@tse, Sfortunatamente, hai ragione. Ma ho aggiornato il mio progetto con la cache, e ora è molto più sicuro. Aggiornerò anche questa risposta oggi. – Oleksandr

+0

Sì, la soluzione funziona, ma crea un sacco di OutOfMemoryException (s). – LaLiLuLeLo

0

Per me il problema si verifica quando: (1) rimuovo un indicatore con un'icona personalizzata o (2) imposta una nuova icona dopo aver creato ...

Per risolvere il primo caso, è necessario impostare l'icona di default prima di rimuovere ...

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

per risolvere il secondo caso, è necessario aggiungere una copia del marcatore con la nuova icona personalizzata e successivamente rimuovere lo stesso primo caso ...

Fino Google Maps squadra risolvere questo problema, è una soluzione ...

Buona fortuna ...

Problemi correlati