제가 진행중인 프로젝트에서 카카오맵 -> 구글맵으로 전환하기로 결정을 했습니다.
다시 구현해보면서 다른점과 어떤 방식으로 구현했는지 기록하고자 글을 적습니다.
Map_kickboard 에서 구글맵을 fragment에 가져와 하나의 클래스에서 하나의 지도에 대한 기능을 구현하고자 했습니다.
Listener 설명
1. GoogleMap.OnCameraIdleListener -> 구글맵에서 맵이동이 끝났을 때 호출되는 리스너입니다.
2. ClusterManager.OnClusterItemClickListener<Cluster_item> -> 이건 이름 그대로 클러스터링 아이템을 클릭했을때 호출되는 리스너입니다. 커스텀마커의 클릭 이벤트를 만들기 위해서 구현했습니다. <Cluster_item>은 클러스터링에 들어갈 마커의 item입니다. 아래의 그림과 같이 implemets에 ClusterItem을 해주시면 됩니다.
public class Cluster_item implements ClusterItem {
private final LatLng mPosition;
public String device_code;
public int brand_tag;
public String device_battery;
public Cluster_item(double lat, double lng, String device_code, String device_battery,int brand_tag){
mPosition = new LatLng(lat, lng);
this.brand_tag = brand_tag;
this.device_code = device_code;
this.device_battery = device_battery;
}
@Override
public LatLng getPosition() {
return mPosition;
}
@Override
public String getTitle() {
return null;
}
@Override
public String getSnippet() {
return null;
}
public int getBrand_tag() {
return brand_tag;
}
public String getDevice_code() {
return device_code;
}
public String getDevice_battery() {
return device_battery;
}
}
*카카오맵과 다르게 구글맵은 onCreate 이후에 맵이 로딩되는 onMapReady(GoogleMap map)이 별도로 존재합니다. 그래서 맵에 관련된 기능들을 이 안에다 구현할 수 있어서 나름 편했습니다. 카카오맵에서는 맵 로딩이 끝나기전에 함수를 호출하게 되는 상황을 피하기 위해 콜백을 따로 구현했어야 했는데 구글맵에는 있습니다.
//마커 클러스터링 준비
mClusterManager = new ClusterManager<>(this, mMap);
mClusterManager.setRenderer(new MarkerRenderer(getApplicationContext(),mMap,mClusterManager));
mClusterManager.setOnClusterItemClickListener(this);
//리스너 달아주기
mMap.setOnCameraIdleListener(mClusterManager);
mMap.setOnMarkerClickListener(mClusterManager);
저기 보이는 mClusterManager.setRenderer 은 클러스터링되는 마커를 커스텀하기 위해 필요한 것입니다. 다양한 것을 랜더링(커스텀) 할 수 있습니다.
private class MarkerRenderer extends DefaultClusterRenderer<Cluster_item>{
public MarkerRenderer(Context context, GoogleMap map, ClusterManager<Cluster_item> clusterManager) {
super(context, map, clusterManager);
}
@Override
public void onClustersChanged(Set<? extends Cluster<Cluster_item>> clusters) {
super.onClustersChanged(clusters);
onCameraIdle();
}
@Override
protected void onBeforeClusterItemRendered(Cluster_item item, MarkerOptions markerOptions) {
super.onBeforeClusterItemRendered(item, markerOptions);
switch (item.getBrand_tag()){
case 21:{
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.marker_swing));
break;
}
case 23:{
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.marker_flower));
break;
}
case 24:{
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.marker_xingxing));
break;
}
case 25:{
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.marker_kickgoing));
break;
}
case 26:{
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.marker_gogosing));
break;
}
default:{
//markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.marker_xingxing));
break;
}
}
}
@Override
public void setOnClusterItemClickListener(ClusterManager.OnClusterItemClickListener<Cluster_item> listener) {
super.setOnClusterItemClickListener(listener);
}
}
onBeforeClusterItemRendered <- 요 함수가 이름 그대로, 클러스터링 하기전에 아이템을 랜더링 하는 것입니다.
저는 커스텀 마커를 만들기 위해서 기존에 Cluster_item의 속성으로 있던 Brand_tag를 가지고 마커 이미지를 변경해주었습니다.
그 결과 브랜드에 따라서 각각의 마커를 커스텀하고 클러스터링을 합쳐서 할 수 있게 되었습니다.
@Override
public boolean onClusterItemClick(Cluster_item cluster_item) {
Toast.makeText(this, cluster_item.getBrand_tag() + " " + cluster_item.getPosition(), Toast.LENGTH_SHORT).show();
switch (cluster_item.getBrand_tag()){
case 21:{
SwingDetailApi swingDetailApi = new SwingDetailApi();
swingDetailApi.execute(cluster_item.device_code);
Intent intent = new Intent(Map_kickboard.this, MarkerActivity_swing.class);
startActivityForResult(intent, 1);
break;
}
case 23:{
MarkerActivity_flower.marker_flower_code = cluster_item.getDevice_code();
MarkerActivity_flower.marker_flower_battery = cluster_item.getDevice_battery();
Intent intent = new Intent(Map_kickboard.this, MarkerActivity_flower.class);
startActivityForResult(intent, 1);
break;
}
case 24:{
MarkerActivity_xing.marker_xing_code = cluster_item.getDevice_code();
MarkerActivity_xing.marker_xing_battery = cluster_item.getDevice_battery();
Intent intent = new Intent(Map_kickboard.this, MarkerActivity_xing.class);
startActivityForResult(intent, 1);
break;
}
case 25:{
MarkerActivity_kickgo.marker_kickgo_code = cluster_item.getDevice_code();
MarkerActivity_kickgo.marker_kickgo_battery = cluster_item.getDevice_battery();
Intent intent = new Intent(Map_kickboard.this, MarkerActivity_kickgo.class);
startActivityForResult(intent, 1);
break;
}
case 26:{
MarkerActivity_gogo.marker_gogosing_code = cluster_item.getDevice_code();
MarkerActivity_gogo.marker_gogosing_battery = cluster_item.getDevice_battery();
Intent intent = new Intent(Map_kickboard.this, MarkerActivity_gogo.class);
startActivityForResult(intent, 1);
break;
}
default:{
//markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.marker_xingxing));
break;
}
}
return true;
}
onClusterItemClick <- 마커 아이템을 클릭했을때 호출됩니다. 여기서 각각의 브랜드에 맞는 마커의 이벤트를 구현할 수 있었습니다.
마지막으로 마커 클릭 이벤트를 만들어 다이얼로그 액티비티와 좌표 토스 메시지를 띄워보았습니다.
설명 글 읽어주셔서 감사합니다. 혹여 틀린 내용, 부족한 것이 있으면 항상 감사히 조언 듣겠습니다.
'개발 > 안드로이드' 카테고리의 다른 글
[안드로이드] 구글맵 커스텀 마커를 하는 2가지 방법 (0) | 2020.03.07 |
---|---|
[안드로이드] 구글맵 클러스터링 커스텀 마커 표출 | 버그리포트 (0) | 2020.01.24 |
[안드로이드]recycleview item의 특정 텍스트 색상 변경 (0) | 2019.10.15 |
[안드로이드] 현재 위치(좌표) 구하기 | 버그리포트 (0) | 2019.10.10 |
[안드로이드] 공공데이터 api 파싱 예시 및 그래프 표현 (0) | 2019.08.15 |
댓글