Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature(#8, #18): 마커 클러스터링 #227

Merged

Conversation

LJG7123
Copy link
Collaborator

@LJG7123 LJG7123 commented Dec 6, 2023

작업 개요

  • 마커 클러스터링을 적용하고, 마커와 관련된 로직을 ClusterManager로 migration
  • 단일 마커 또는 복수 마커 클릭 시 지도 조작 비활성화
  • 복수 마커 클릭 시 등록된 스냅 포인트 화면으로 이동

작업 사항

  • Maps SDK 유틸리티를 사용하여 ClusterItemClusterRenderer를 구현하고, 이를 이용하여 ClusterManager를 구현하였다.
  • 기존에 googleMap 객체에 마커를 추가하고 제거하던 것을, ClusterManagerClusterItem을 추가하고 제거하도록 수정하였다.
  • 지도에서 단일 혹은 복수 마커 클릭 시 상단바가 나타나는데, 이 때 지도 조작이 불가능해지도록 수정하였다.
  • 클러스터(복수 마커) 클릭 시 ClusterListFragment에 해당 클러스터에 포함된 마커들의 태그를 전달하고, 태그에 해당하는 사진들을 등록된 스냅 포인트 화면에 보여주도록 RecyclerView를 구현하였다.

고민한 점들(필수 X)

  • 지도의 줌을 조정할 때 마다 onClusterUpdated 콜백이 호출되는데, 그러면 선택된 마커가 클러스터링 될 때 문제가 생길 것 같아 팀원들과 의논한 후 마커나 클러스터가 선택된 상태일 때는 지도 조작이 불가능하도록 설정하기로 결정하였다.

스크린샷(필수 X)

import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.model.BitmapDescriptorFactory
import com.google.android.gms.maps.model.Marker
import com.google.android.gms.maps.model.MarkerOptions

val clusterTextSize = CLUSTER_TEXT_SIZE.pxFloat()
val clusterCircleRadius = (CLUSTER_TEXT_SIZE / 2 + 1).pxFloat()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

변수는 외부에서 쓰는 게 아니면 private로 선언하는 게 좋을 것 같아요.

Comment on lines 16 to 25
class ClusterListFragment : BaseFragment<FragmentClusterListBinding>(R.layout.fragment_cluster_list) {

private val clusterListViewModel: ClusterListViewModel by viewModels()
private val mainViewModel: MainViewModel by activityViewModels()
private val args: ClusterListFragmentArgs by navArgs()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mainViewModel.onPreviewFragmentShowing()
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ClusterListFragment에서 onPreviewFragmentShowing를 호출하고 있는데요, 두 요소의 이름이 안 어울리는 것 같아요.
ClusterListFragment도 일종의 사진 미리보기 화면이니까 ClusterPreviewFragment로 하거나
아니면 함수의 동작을 나타내도록 setPreviewModeEnabled/Disabled로 하는게 좋을 것 같아요.
제가 만든 함수지만 다시 보니까 이름이 이상하긴 하네요 ㅋㅋ

Copy link
Collaborator

@rbybound rbybound left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

어려워 보이는 클러스터링을 어떻게든 해내셨네요.
고생하셨어요. 👍

@@ -177,6 +178,11 @@ class MainActivity(
is MainActivityEvent.GetAroundPostFailed -> {
showToastMessage(R.string.get_around_posts_failed)
}

is MainActivityEvent.NavigateCluster -> {
val bundle = bundleOf("tags" to event.tags.toTypedArray())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

하드코딩된 string을 상수로 관리하면 좋을 것 같아요.
bundle 변수를 선언하는 부분도 함수에서 처리하면 좋을 것 같아요!

Comment on lines 209 to 213
mapManager.setZoomGesturesEnabled(it.isPreviewFragmentShowing.not())
mapManager.setScrollGesturesEnabled(it.isPreviewFragmentShowing.not())
if (!it.isPreviewFragmentShowing) {
mapManager.removeFocus()
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 isPreviewFragmentShowing에 따라 행동을 하는 함수로 빼면 좋을 것 같아요


init {
clusterManager.renderer = this
minClusterSize = 2
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minclustersize의 의미와, 2의 의미는 뭘까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

클러스터링 하기 위한 마커의 최소 개수인데, Default가 4라서 2로 설정해줬습니다. 이것도 따로 상수로 빼는게 좋겠네요

import android.os.Parcelable
import kotlinx.parcelize.Parcelize

@Parcelize
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이미 사용중인 kotlinx.serialization으로 해결이 안되는걸까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

args로 넘겨줄 때 serializable은 java.io.Serializable 이라서, 자바 쪽 라이브러리 보다는 코틀린 라이브러리를 사용하는 게 낫다고 생각했습니다

@LJG7123 LJG7123 requested a review from wsb7788 December 7, 2023 02:20
Copy link
Collaborator

@wsb7788 wsb7788 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생많으셨습니다 !

@LJG7123 LJG7123 merged commit 2b9910a into boostcampwm2023:develop Dec 7, 2023
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment