2015-06-21 81 views
15

是否有任何方法可以更改集羣項目的背景顏色? (顯示標記計數的標記,例如100+,200+ ...)。我試圖查看ClusterManager的源代碼,但找不到任何改變顏色的選項,但也許這裏有人知道如何做到這一點。我基本上想要「體會」那些顏色。Android maps utils集羣圖標顏色

回答

21

我能夠通過使用圖書館樣本中的this demo作爲指導,得到一個粗略的實現工作。

我使用了來自here的材料設計圖標中的lens圖標。在下載lens zip後,我把ic_lens_black_24dp.png放在可繪製的文件夾下。然後我使用Drawable.setColorFilter()方法更改代碼中的默認顏色。

我也能夠改變默認的標記顏色,並認爲我也會在這裏包括它。

首先,通過調用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)); 
     } 
    } 
} 

結果:

初始應用程序啓動:

No clustering

縮小時,一些集羣:

initial clustering

放大了一遍,所有的標記集羣:

all Markers clustered

+0

謝謝。我可以有不同的顏色,如藍色5和紅色10? – qwertz

+0

@qwertz是的,你應該可以使用'cluster.getSize()'並相應地改變集羣的顏色。 –

+0

好的,謝謝:) – qwertz

9

我花了一些超類的方法並部分重新編譯它們。現在我擁有自己的顏色,美麗的標準集羣。

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)); 
+0

謝謝,我會檢查出來 – qwertz

+0

這是代碼形式的魔法謝謝! – danguilherme

+0

mColoredCircleBackground.getPaint() .setColor(clusterColor);不工作在發佈代碼上。我的意思是簽名的apk。任何其他方式嗎? – Panache

3

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

這將更改羣集顏色爲粉紅色,在由分定義的顏色(最大)紅(綠,藍)的範圍內。希望有所幫助!

+0

這是最好的答案 – 2016-02-04 16:21:02

+0

我不認爲改變一個庫的源代碼會有很大幫助,它會使庫的更新容易出錯 – Leukipp

13

我們可以在CustomClusterRenderer中覆蓋getColor。

public class CustomClusterRenderer extends DefaultClusterRenderer<CustomClusterItem> { 

@Override 
    protected int getColor(int clusterSize) { 
     return Color.parseColor("#567238"); 
    } 
} 
+0

Th謝謝你,很好的解決方案! –

+0

如何使用它?當我只是將此代碼添加到我的項目時,它顯示我錯誤 - com.google.maps.clustering.view中沒有默認構造函數。 DefaultClusterRenderer' – kashlo

+0

最好的解決方案通常很簡單。 – okkko

0

尼斯定製渲染器集羣居中的文本和不同的大小:

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

enter image description here