Android maps utils Цвет значка кластера

Есть ли способ изменить цвет фона элемента кластера? (Тот, который отображает количество маркеров, например 100+, 200+ …). Я попытался заглянуть в исходный код ClusterManager, но не смог найти никакой опции для изменения цвета, но, возможно, кто-то здесь знает, как это сделать. Я в основном хочу немного «материализировать» эти цвета.

Solutions Collecting From Web of "Android maps utils Цвет значка кластера"

Я смог получить грубую реализацию, используя эту демонстрацию из образцов библиотеки в качестве руководства.

Здесь я использовал значок lens из Иконки дизайна материалов. После загрузки zip lens я помещаю ic_lens_black_24dp.png в папку с возможностью ic_lens_black_24dp.png . Затем я использовал метод Drawable.setColorFilter () для изменения цвета по умолчанию в коде.

Я также смог изменить цвет маркера по умолчанию, и решил, что я включу это также здесь.

Сначала установите Renderer, вызвав setRenderer() :

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

Затем определите класс 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)); } } 

Код полного класса:

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

Результат:

Первоначальный запуск приложения:

Нет кластеризации

Масштабирование, некоторые кластеризации:

Начальная кластеризация

Выбрав снова, все маркеры сгруппированы:

Все кластеры маркеров

Мы можем переопределить getColor в CustomClusterRenderer.

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

Я взял некоторые методы суперкласса и частично переделал их. Теперь у меня есть красивые стандартные кластеры с моими собственными цветами.

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

А затем установите средство визуализации в диспетчер кластеров

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

Перейдите в DefaultClusterRenderer (пакет com.google.maps.android.clustering.view;) и измените метод getColor () на это:

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

Это изменит цвет кластера на розовый, в диапазоне цвета, определяемом минимальным (макс.) Красным (зеленый, синий). Надеюсь, что поможет!