Android 地图实用程序集群图标颜色
Android maps utils cluster icon color
有什么方法可以改变集群项的背景颜色吗? (显示标记计数的那个,例如 100+、200+ ...)。我试图查看 ClusterManager 的源代码,但找不到任何更改颜色的选项,但也许这里有人知道该怎么做。我基本上想"materialify"那些颜色一点。
通过使用库示例中的 this demo 作为指南,我能够得到一个粗略的实现。
我使用 Material 设计图标 here. After downloading the lens
zip I put ic_lens_black_24dp.png
under the drawable folder. Then I used the Drawable.setColorFilter() 方法中的 lens
图标来更改代码中的默认颜色。
我还能够更改默认的标记颜色,并且我想我也会在此处包含它。
首先,通过调用 setRenderer()
:
设置渲染器
mClusterManager.setRenderer(new MyClusterRenderer(this, mMap,
mClusterManager));
然后,定义MyClusterRenderer
class:
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));
}
}
完整 class 代码:
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));
}
}
}
结果:
初始应用启动:
缩小,一些聚类:
再次缩小,所有标记聚集在一起:
我采用了超类的一些方法并对其进行了部分改造。现在我有漂亮的标准簇,有我自己的颜色。
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
// });
}
这会将簇颜色更改为粉红色,在由 min(max) red(green, blue) 定义的颜色范围内。希望有所帮助!
我们可以重写 CustomClusterRenderer 中的 getColor。
public class CustomClusterRenderer extends DefaultClusterRenderer<CustomClusterItem> {
@Override
protected int getColor(int clusterSize) {
return Color.parseColor("#567238");
}
}
具有居中文本和不同大小的簇的漂亮自定义渲染器:
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;
}
}
遗憾的是,覆盖 getColor
对我不起作用。但这看起来足以改变标记颜色(和其他东西):
class ClusterItemRenderer(
context: Context, map: GoogleMap,
clusterManager: ClusterManager<ClusterMarker>
) : DefaultClusterRenderer<ClusterMarker>(context, map, clusterManager) {
override fun onBeforeClusterItemRendered(item: ClusterMarker, markerOptions: MarkerOptions) {
val markerDescriptor = BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA)
markerOptions.icon(markerDescriptor)
}
}
也可以根据recommendations添加更新:
If you're using custom clustering (i.e, if you're extending
DefaultClusterRenderer
), you must override two additional methods in
v1:
onClusterItemUpdated()
- should be the same* as your onBeforeClusterItemRendered()
method
onClusterUpdated()
- should be the same* as your onBeforeClusterRendered()
method
*Note that these methods can't be identical, as you need to use a Marker
instead of MarkerOptions
override fun onClusterItemUpdated(item: ClusterMarker, marker: Marker) {
val markerDescriptor = BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA)
marker.setIcon(markerDescriptor)
}
有什么方法可以改变集群项的背景颜色吗? (显示标记计数的那个,例如 100+、200+ ...)。我试图查看 ClusterManager 的源代码,但找不到任何更改颜色的选项,但也许这里有人知道该怎么做。我基本上想"materialify"那些颜色一点。
通过使用库示例中的 this demo 作为指南,我能够得到一个粗略的实现。
我使用 Material 设计图标 here. After downloading the lens
zip I put ic_lens_black_24dp.png
under the drawable folder. Then I used the Drawable.setColorFilter() 方法中的 lens
图标来更改代码中的默认颜色。
我还能够更改默认的标记颜色,并且我想我也会在此处包含它。
首先,通过调用 setRenderer()
:
mClusterManager.setRenderer(new MyClusterRenderer(this, mMap,
mClusterManager));
然后,定义MyClusterRenderer
class:
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));
}
}
完整 class 代码:
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));
}
}
}
结果:
初始应用启动:
缩小,一些聚类:
再次缩小,所有标记聚集在一起:
我采用了超类的一些方法并对其进行了部分改造。现在我有漂亮的标准簇,有我自己的颜色。
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
// });
}
这会将簇颜色更改为粉红色,在由 min(max) red(green, blue) 定义的颜色范围内。希望有所帮助!
我们可以重写 CustomClusterRenderer 中的 getColor。
public class CustomClusterRenderer extends DefaultClusterRenderer<CustomClusterItem> {
@Override
protected int getColor(int clusterSize) {
return Color.parseColor("#567238");
}
}
具有居中文本和不同大小的簇的漂亮自定义渲染器:
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;
}
}
遗憾的是,覆盖 getColor
对我不起作用。但这看起来足以改变标记颜色(和其他东西):
class ClusterItemRenderer(
context: Context, map: GoogleMap,
clusterManager: ClusterManager<ClusterMarker>
) : DefaultClusterRenderer<ClusterMarker>(context, map, clusterManager) {
override fun onBeforeClusterItemRendered(item: ClusterMarker, markerOptions: MarkerOptions) {
val markerDescriptor = BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA)
markerOptions.icon(markerDescriptor)
}
}
也可以根据recommendations添加更新:
If you're using custom clustering (i.e, if you're extending
DefaultClusterRenderer
), you must override two additional methods in v1:
onClusterItemUpdated()
- should be the same* as youronBeforeClusterItemRendered()
methodonClusterUpdated()
- should be the same* as youronBeforeClusterRendered()
method*Note that these methods can't be identical, as you need to use a
Marker
instead ofMarkerOptions
override fun onClusterItemUpdated(item: ClusterMarker, marker: Marker) {
val markerDescriptor = BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA)
marker.setIcon(markerDescriptor)
}