はじめに
最近GoogleMapマーカークラスタに触れる機会があり、その際にクラスタをカスタマイズをする必要がありました。調査の過程で知ったカスタマイズ方法を少し紹介します。
クラスタ内のアイテムクラス
公式ドキュメントにもあるように、クラスタ内に入れるアイテムとして、ClusterItemインタフェースを実装したクラスを用意します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public class MyItem implements ClusterItem { private final LatLng mPosition; private String mTitle; private String mSnippet; public MyItem(double lat, double lng, String title, String snippet) { mPosition = new LatLng(lat, lng); mTitle = title; mSnippet = snippet; } @Override public LatLng getPosition() { return mPosition; } @Override public String getTitle() { return mTitle; } @Override public String getSnippet() { return mSnippet; } public void setTitle(String title) { mTitle = title; } public void setSnippet(String snippet) { mSnippet = snippet; } } |
クラスタをレンダリングするクラス
DefaultClusterRendererを継承して、独自のレンダリング用クラスを作成します。
このCustomRendererで、親クラスのメソッドをオーバーライドすることで、見た目や挙動を変えていくことができます。
1 2 3 4 5 6 | public class CustomRenderer extends DefaultClusterRenderer<MyItem> { public CustomRenderer(Context context, GoogleMap map, ClusterManager<MyItem> clusterManager) { super(context, map, clusterManager); } } |
クラスタの色を設定する
親クラスのDefaultClusterRendererでは
private static final int[] BUCKETS = {10, 20, 50, 100, 200, 500, 1000};
というクラスタ内のアイテム数の区分を設定して、それぞれ別の色になるように設定しています。これを変えたい場合はCustomRendererでgetColorをオーバーライドします。
1 2 3 4 | @Override protected int getColor(int clusterSize) { return Color.rgb(0, 255, 255); // 常に#00ffff } |
クラスタ化の最小個数を設定する
CustomRendererでshouldRenderAsClusterをオーバーライドします。
1 2 3 4 5 | @Override protected boolean shouldRenderAsCluster(Cluster cluster) { // アイテムが5個以上ならクラスタ化 return cluster.getSize() > 4; } |
クラスタのクリックイベントを拾う
アクティビティもしくはフラグメントで、onClusterClickをオーバーライドします。
下記のコードでは、クラスタ内の1番目のアイテムを取得し、その位置にカメラを移動しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | public class SampleActivity extends Activity implements OnMapReadyCallback, ClusterManager.OnClusterClickListener<MyItem>{ private GoogleMap mGoogleMap; private ClusterManager<MyItem> mClusterManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sample); MapView mapView = findViewById(R.id.map_view); mapView.getMapAsync(this); mClusterManager = new ClusterManager<MyItem>(this, mGoogleMap); mClusterManager.setRenderer(new CustomRenderer(this, mGoogleMap, mClusterManager)); mGoogleMap.setOnMarkerClickListener(mClusterManager); mClusterManager.setOnClusterClickListener(this); } @Override public void onMapReady(GoogleMap map) { if (mGoogleMap != null) { return; } mGoogleMap = map; } @Override public boolean onClusterClick(Cluster<MyItem> cluster) { try { CameraPosition cameraPosition = new CameraPosition.Builder() .target(cluster.getItems().iterator().next().getPosition()) .zoom(10) .build(); mGoogleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); } catch (Exception e) { e.printStackTrace(); } return true; } } |
さいごに
いかがでしたでしょうか。
Android Studioでさくっとビルドして、挙動を見つつコードを確認できますので、興味がある方はドキュメントだけでなく、公式のデモアプリに触ってみることをおすすめします。