我有一个 android 应用程序,其中的地图填充了具有销售属性的模型。
我能够实现自定义ClusterRenderer
以在集群图标上显示总销售额而不是集群大小。
我遇到的问题是例如。
Cluster
A 有 5 个ClusterItems
,总销售额为 100 万
Cluster
B 有 15 个ClusterItems
,总销售额为 100k
由于集群的默认行为,集群 B 比集群 A 大(因为它有更多ClusterItems
)
有没有办法让我劫持渲染器,以便集群标记的大小与我的总销售额而不是集群大小一起缩放?
任何帮助将不胜感激!
添加我的 clusterrenderer 代码
public class MyClusterRenderer extends DefaultClusterRenderer<Store> {
private final NavigableMap<Long, String> suffixes = new TreeMap<>();
private IconGenerator mClusterIconGenerator;
private Context context;
//for cluster icon
private ShapeDrawable mColoredCircleBackground;
public MyClusterRenderer(Context context, GoogleMap map, ClusterManager<Store> clusterManager) {
super(context, map, clusterManager);
this.context = context;
//for label prefix processing
suffixes.put(1_000L, "k");
suffixes.put(1_000_000L, "M");
suffixes.put(1_000_000_000L, "G");
suffixes.put(1_000_000_000_000L, "T");
suffixes.put(1_000_000_000_000_000L, "P");
suffixes.put(1_000_000_000_000_000_000L, "E");
mClusterIconGenerator = new IconGenerator(context);
//pre processing for cluster icons
mClusterIconGenerator.setContentView(makeSquareTextView(context));
mClusterIconGenerator.setTextAppearance(R.style.amu_ClusterIcon_TextAppearance);
mClusterIconGenerator.setBackground(makeClusterBackground());
}
private SquareTextView makeSquareTextView(Context context) {
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.amu_text);
int twelveDpi = 12 * getDensity();
squareTextView.setPadding(twelveDpi, twelveDpi, twelveDpi, twelveDpi);
return squareTextView;
}
@Override
protected void onBeforeClusterItemRendered(Store item, MarkerOptions markerOptions) {
//individual markers here
markerOptions.icon(getIcon(item));
super.onBeforeClusterItemRendered(item, markerOptions);
}
@Override
protected void onBeforeClusterRendered(Cluster<Store> cluster, MarkerOptions markerOptions) {
Bitmap icon = mClusterIconGenerator.makeIcon(getTotalSalesWithFormat((List<Store>) cluster.getItems()));
BitmapDescriptor descriptor = BitmapDescriptorFactory.fromBitmap(icon);
markerOptions.icon(descriptor);
}
private int getDensity(){
return (int) context.getResources().getDisplayMetrics().density;
}
private LayerDrawable makeClusterBackground() {
mColoredCircleBackground = new ShapeDrawable(new OvalShape());
mColoredCircleBackground.setColorFilter(context.getResources().getColor(R.color.My_green), PorterDuff.Mode.SRC_ATOP);
ShapeDrawable outline = new ShapeDrawable(new OvalShape());
outline.getPaint().setColor(context.getResources().getColor(android.R.color.transparent)); // Transparent white.
LayerDrawable background = new LayerDrawable(new Drawable[]{outline, mColoredCircleBackground});
int strokeWidth = getDensity() * 3;
background.setLayerInset(1, strokeWidth, strokeWidth, strokeWidth, strokeWidth);
return background;
}
private String getTotalSalesWithFormat(List<Store> list){
return format(getTotalSales(list));
}
private int getTotalSales(List<Store> list){
int sum = 0;
for(Store s : list){
sum += s.getSales();
}
return sum;
}
private BitmapDescriptor getIcon(Store item){
Bitmap bmp = BitmapFactory.decodeResource(context.getResources(), R.drawable.circle);
Bitmap mutable = bmp.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(mutable);
Paint p = new Paint();
p.setColor(Color.WHITE);
canvas.drawText(String.valueOf(item.getSales()), 0, 50, p);
return BitmapDescriptorFactory.fromBitmap(mutable);
}
private String format(long value) {
//Long.MIN_VALUE == -Long.MIN_VALUE so we need an adjustment here
if (value == Long.MIN_VALUE) return format(Long.MIN_VALUE + 1);
if (value < 0) return "-" + format(-value);
if (value < 1000) return Long.toString(value); //deal with easy case
Map.Entry<Long, String> e = suffixes.floorEntry(value);
Long divideBy = e.getKey();
String suffix = e.getValue();
long truncated = value / (divideBy / 10); //the number part of the output times 10
boolean hasDecimal = truncated < 100 && (truncated / 10d) != (truncated / 10);
return hasDecimal ? (truncated / 10d) + suffix : (truncated / 10) + suffix;
}
}