utils studio para marcadores libreria google clustering cluster android google-maps google-maps-markers markerclusterer

studio - Android mapea el color del icono del cluster utils



libreria google maps android studio (5)

¿Hay algún método para cambiar el color de fondo del elemento del clúster? (el que muestra el recuento de los marcadores, como 100+, 200+ ...). Intenté buscar en el código fuente del ClusterManager pero no pude encontrar ninguna opción para cambiar el color, pero tal vez alguien aquí sepa cómo hacerlo. Básicamente quiero "materializar" esos colores un poco.


Buen renderizador personalizado con texto centrado y diferentes tamaños de grupos:

public class MyClusterRenderer extends DefaultClusterRenderer<Station> { private final IconGenerator mClusterIconGeneratorBig = new IconGenerator(getCtx()); private final IconGenerator mClusterIconGeneratorMed = new IconGenerator(getCtx()); private final IconGenerator mClusterIconGeneratorSml = new IconGenerator(getCtx()); final Drawable clusterIconBig = getResources().getDrawable(R.drawable.marker1); final Drawable clusterIconMed = getResources().getDrawable(R.drawable.marker2); final Drawable clusterIconSml = getResources().getDrawable(R.drawable.marker3); public MyClusterRenderer(Context context, GoogleMap map, ClusterManager<Station> clusterManager) { super(context, map, clusterManager); setupIconGen(mClusterIconGeneratorBig, clusterIconBig, context); setupIconGen(mClusterIconGeneratorMed, clusterIconMed, context); setupIconGen(mClusterIconGeneratorSml, clusterIconSml, context); } private void setupIconGen(IconGenerator generator, Drawable drawable, Context context) { TextView textView = new TextView(context); textView.setTextAppearance(context, R.style.BubbleText); textView.setTypeface(App.FONTS[2]); textView.setId(com.google.maps.android.R.id.amu_text); textView.setGravity(android.view.Gravity.CENTER); textView.setLayoutParams(new FrameLayout.LayoutParams(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight())); generator.setContentView(textView); generator.setBackground(drawable); } @Override protected void onBeforeClusterItemRendered(Station item, MarkerOptions markerOptions) { BitmapDescriptor markerDescriptor = BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA); markerOptions.icon(markerDescriptor); } @Override protected void onClusterItemRendered(Station clusterItem, Marker marker) { super.onClusterItemRendered(clusterItem, marker); } @Override protected void onBeforeClusterRendered(Cluster<Station> cluster, MarkerOptions markerOptions) { if (cluster.getSize() > 20) { Bitmap icon = mClusterIconGeneratorBig.makeIcon(String.valueOf(cluster.getSize())); markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon)); } else if (cluster.getSize() > 10) { Bitmap icon = mClusterIconGeneratorMed.makeIcon(String.valueOf(cluster.getSize())); markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon)); } else { Bitmap icon = mClusterIconGeneratorSml.makeIcon(String.valueOf(cluster.getSize())); markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon)); } } @Override protected boolean shouldRenderAsCluster(Cluster cluster) { return cluster.getSize() > 5; } }


Podemos anular getColor en CustomClusterRenderer.

public class CustomClusterRenderer extends DefaultClusterRenderer<CustomClusterItem> { @Override protected int getColor(int clusterSize) { return Color.parseColor("#567238"); } }


Pude obtener una implementación aproximada al usar esta demostración de los ejemplos de la biblioteca como guía.

lens ícono de la lens de los íconos de diseño de materiales desde here Después de descargar el zip de la lens , puse ic_lens_black_24dp.png debajo de la carpeta ic_lens_black_24dp.png . Luego usé el método Drawable.setColorFilter() para cambiar el color predeterminado en el código.

También pude cambiar el color de marcador predeterminado, y pensé que también lo incluiría aquí.

Primero, establezca un Renderer llamando a setRenderer() :

mClusterManager.setRenderer(new MyClusterRenderer(this, mMap, mClusterManager));

Luego, define la clase MyClusterRenderer :

public class MyClusterRenderer extends DefaultClusterRenderer<MyItem> { private final IconGenerator mClusterIconGenerator = new IconGenerator(getApplicationContext()); public MyClusterRenderer(Context context, GoogleMap map, ClusterManager<MyItem> clusterManager) { super(context, map, clusterManager); } @Override protected void onBeforeClusterItemRendered(MyItem item, MarkerOptions markerOptions) { BitmapDescriptor markerDescriptor = BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA); markerOptions.icon(markerDescriptor); } @Override protected void onClusterItemRendered(MyItem clusterItem, Marker marker) { super.onClusterItemRendered(clusterItem, marker); } @Override protected void onBeforeClusterRendered(Cluster<MyItem> cluster, MarkerOptions markerOptions){ final Drawable clusterIcon = getResources().getDrawable(R.drawable.ic_lens_black_24dp); clusterIcon.setColorFilter(getResources().getColor(android.R.color.holo_orange_light), PorterDuff.Mode.SRC_ATOP); mClusterIconGenerator.setBackground(clusterIcon); //modify padding for one or two digit numbers if (cluster.getSize() < 10) { mClusterIconGenerator.setContentPadding(40, 20, 0, 0); } else { mClusterIconGenerator.setContentPadding(30, 20, 0, 0); } Bitmap icon = mClusterIconGenerator.makeIcon(String.valueOf(cluster.getSize())); markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon)); } }

Código de clase completo:

public class MapsActivity extends AppCompatActivity implements ClusterManager.OnClusterItemInfoWindowClickListener<MyItem> { private ClusterManager<MyItem> mClusterManager; private MyItem clickedClusterItem; private GoogleMap mMap; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_maps); setUpMapIfNeeded(); } @Override protected void onResume() { super.onResume(); setUpMapIfNeeded(); } private void setUpMapIfNeeded() { // Do a null check to confirm that we have not already instantiated the map. if (mMap == null) { // Try to obtain the map from the SupportMapFragment. mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)) .getMap(); // Check if we were successful in obtaining the map. if (mMap != null) { setUpMap(); } } } private void setUpMap() { mMap.getUiSettings().setMapToolbarEnabled(true); mMap.getUiSettings().setZoomControlsEnabled(true); mMap.setMyLocationEnabled(true); mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); mClusterManager = new ClusterManager<>(this, mMap); mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(37.779977,-122.413742), 10)); mMap.setOnCameraChangeListener(mClusterManager); mMap.setOnMarkerClickListener(mClusterManager); mClusterManager.setRenderer(new MyClusterRenderer(this, mMap, mClusterManager)); mMap.setInfoWindowAdapter(mClusterManager.getMarkerManager()); mMap.setOnInfoWindowClickListener(mClusterManager); //added mClusterManager.setOnClusterItemInfoWindowClickListener(this); //added mClusterManager .setOnClusterItemClickListener(new ClusterManager.OnClusterItemClickListener<MyItem>() { @Override public boolean onClusterItemClick(MyItem item) { clickedClusterItem = item; return false; } }); addItems(); mClusterManager.getMarkerCollection().setOnInfoWindowAdapter( new MyCustomAdapterForItems()); } private void addItems() { double latitude = 37.779977; double longitude = -122.413742; for (int i = 0; i < 10; i++) { double offset = i / 60d; double lat = latitude + offset; double lng = longitude + offset; MyItem offsetItem = new MyItem(lat, lng, "title " + i+1, "snippet " + i+1); mClusterManager.addItem(offsetItem); } } //added with edit @Override public void onClusterItemInfoWindowClick(MyItem myItem) { //Cluster item InfoWindow clicked, set title as action Intent i = new Intent(this, OtherActivity.class); i.setAction(myItem.getTitle()); startActivity(i); //You may want to do different things for each InfoWindow: if (myItem.getTitle().equals("some title")){ //do something specific to this InfoWindow.... } } public class MyCustomAdapterForItems implements GoogleMap.InfoWindowAdapter { private final View myContentsView; MyCustomAdapterForItems() { myContentsView = getLayoutInflater().inflate( R.layout.info_window, null); } @Override public View getInfoWindow(Marker marker) { TextView tvTitle = ((TextView) myContentsView .findViewById(R.id.txtTitle)); TextView tvSnippet = ((TextView) myContentsView .findViewById(R.id.txtSnippet)); tvTitle.setText(clickedClusterItem.getTitle()); tvSnippet.setText(clickedClusterItem.getSnippet()); return myContentsView; } @Override public View getInfoContents(Marker marker) { return null; } } public class MyClusterRenderer extends DefaultClusterRenderer<MyItem> { private final IconGenerator mClusterIconGenerator = new IconGenerator(getApplicationContext()); public MyClusterRenderer(Context context, GoogleMap map, ClusterManager<MyItem> clusterManager) { super(context, map, clusterManager); } @Override protected void onBeforeClusterItemRendered(MyItem item, MarkerOptions markerOptions) { BitmapDescriptor markerDescriptor = BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA); markerOptions.icon(markerDescriptor); } @Override protected void onClusterItemRendered(MyItem clusterItem, Marker marker) { super.onClusterItemRendered(clusterItem, marker); } @Override protected void onBeforeClusterRendered(Cluster<MyItem> cluster, MarkerOptions markerOptions){ final Drawable clusterIcon = getResources().getDrawable(R.drawable.ic_lens_black_24dp); clusterIcon.setColorFilter(getResources().getColor(android.R.color.holo_orange_light), PorterDuff.Mode.SRC_ATOP); mClusterIconGenerator.setBackground(clusterIcon); //modify padding for one or two digit numbers if (cluster.getSize() < 10) { mClusterIconGenerator.setContentPadding(40, 20, 0, 0); } else { mClusterIconGenerator.setContentPadding(30, 20, 0, 0); } Bitmap icon = mClusterIconGenerator.makeIcon(String.valueOf(cluster.getSize())); markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon)); } } }

Resultado:

Lanzamiento inicial de la aplicación:

Alejando, algunos agrupamientos:

Al alejarse de nuevo, todos los marcadores se agruparon:


Tomé algunos métodos de superclase y los rehice parcialmente. Ahora tengo hermosos grupos estándar con mis propios colores.

public class CustomClusterRenderer extends DefaultClusterRenderer<GoogleMapMarker> { private final IconGenerator mIconGenerator; private ShapeDrawable mColoredCircleBackground; private SparseArray<BitmapDescriptor> mIcons = new SparseArray(); private final float mDensity; private Context mContext; public CustomClusterRenderer(Context context, GoogleMap map, ClusterManager<GoogleMapMarker> clusterManager) { super(context, map, clusterManager); this.mContext = context; this.mDensity = context.getResources().getDisplayMetrics().density; this.mIconGenerator = new IconGenerator(context); this.mIconGenerator.setContentView(this.makeSquareTextView(context)); this.mIconGenerator.setTextAppearance( com.google.maps.android.R.style.ClusterIcon_TextAppearance); this.mIconGenerator.setBackground(this.makeClusterBackground()); } @Override protected void onBeforeClusterRendered(Cluster<GoogleMapMarker> cluster, MarkerOptions markerOptions) { // Main color int clusterColor = mContext.getResources().getColor(R.color.colorPrimary); int bucket = this.getBucket(cluster); BitmapDescriptor descriptor = this.mIcons.get(bucket); if(descriptor == null) { this.mColoredCircleBackground.getPaint().setColor(clusterColor); descriptor = BitmapDescriptorFactory.fromBitmap( this.mIconGenerator.makeIcon(this.getClusterText(bucket))); this.mIcons.put(bucket, descriptor); } markerOptions.icon(descriptor); } private SquareTextView makeSquareTextView(Context context) { SquareTextView squareTextView = new SquareTextView(context); ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(-2, -2); squareTextView.setLayoutParams(layoutParams); squareTextView.setId(com.google.maps.android.R.id.text); int twelveDpi = (int)(12.0F * this.mDensity); squareTextView.setPadding(twelveDpi, twelveDpi, twelveDpi, twelveDpi); return squareTextView; } private LayerDrawable makeClusterBackground() { // Outline color int clusterOutlineColor = mContext.getResources().getColor(R.color.colorWhite); this.mColoredCircleBackground = new ShapeDrawable(new OvalShape()); ShapeDrawable outline = new ShapeDrawable(new OvalShape()); outline.getPaint().setColor(clusterOutlineColor); LayerDrawable background = new LayerDrawable( new Drawable[]{outline, this.mColoredCircleBackground}); int strokeWidth = (int)(this.mDensity * 3.0F); background.setLayerInset(1, strokeWidth, strokeWidth, strokeWidth, strokeWidth); return background; }

Y luego configurar el renderizador a Cluster Manager

mClusterManager = new ClusterManager<>(context, mGoogleMap); mClusterManager.setRenderer(new CustomClusterRenderer(context, mGoogleMap, mClusterManager));


Vaya a DefaultClusterRenderer (paquete com.google.maps.android.clustering.view;) y cambie el método getColor () a esto:

private int getColor(int clusterSize) { // custom color double _logClusterSize; // log final int _maxRed = Integer.parseInt("ff", 16); // Log.v("kai", String.valueOf(_maxRed)); final int _minRed = Integer.parseInt("e6", 16); final int _maxGreen = Integer.parseInt("a2", 16); final int _minGreen = Integer.parseInt("47", 16); final int _maxBlue = Integer.parseInt("93", 16); final int _minBlue = Integer.parseInt("2d", 16); final double _maxLogClusterSize = 10; double _step = (_maxRed - _minRed) / _maxLogClusterSize; _logClusterSize = Math.log(clusterSize); if(_logClusterSize > 10) _logClusterSize = 10; int _red = _maxRed - (int) (_step * _logClusterSize); int _green = _maxGreen - (int) (_step * _logClusterSize); int _blue = _maxBlue - (int) (_step * _logClusterSize); return Color.rgb(_red, _green, _blue); // final float hueRange = 220; // final float sizeRange = 300; // final float size = Math.min(clusterSize, sizeRange); // final float hue = (sizeRange - size) * (sizeRange - size) / (sizeRange * sizeRange) * hueRange; // return Color.HSVToColor(new float[]{ // hue, 1f, .6f // }); }

Esto cambiará el color del Cluster a rosa, en el rango del color definido por min (max) red (green, blue). Espero que la ayuda!