모바일 앱(안드로이드)

Jetpack Compose를 이용한 Kakao Map LOD 라벨 추가 및 클릭 이벤트 처리 예제 (feat Kakao MAP)

Billcorea 2024. 11. 8. 15:20
반응형

Jetpack Compose를 이용한 Kakao Map LOD 라벨 추가 및 클릭 이벤트 처리 예제

귀요미 ???

 

이 예제에서는 Jetpack Compose에서 AndroidView를 사용하여 Kakao Map을 표시하고, LOD 라벨을 추가 및 클릭 이벤트를 처리하는 방법을 설명합니다.

1. 프로젝트 설정

먼저 build.gradle 파일에 Kakao Map SDK 의존성을 추가합니다.

groovy
dependencies {
    implementation 'net.daum.mf.map.api:openapi-android-maps:1.4.0'
    implementation 'androidx.compose.ui:ui:1.2.0'
    implementation 'androidx.compose.material:material:1.2.0'
    implementation 'androidx.compose.ui:ui-tooling-preview:1.2.0'
}

2. LOD 라벨 추가 및 클릭 이벤트 처리

Kotlin 코드:

kotlin
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.viewinterop.AndroidView
import com.kakao.map.MapView
import com.kakao.map.model.MapPoint

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyApp()
        }
    }
}

@Composable
fun MyApp() {
    KakaoMapView()
}

@Composable
fun KakaoMapView() {
    val context = LocalContext.current
    val mapView = remember {MapView(context)}
    
    AndroidView(
                modifier = Modifier.fillMaxSize(), // AndroidView의 높이 임의 설정
                factory = { context ->
                    mapView.apply {
                        mapView.start(
                            object : MapLifeCycleCallback() {
                                // 지도 생명 주기 콜백: 지도가 파괴될 때 호출
                                override fun onMapDestroy() {
                                    // 필자가 직접 만든 Toast생성 함수
                                    //makeToast(context = context, message = "지도를 불러오는데 실패했습니다.")
                                }

                                // 지도 생명 주기 콜백: 지도 로딩 중 에러가 발생했을 때 호출
                                override fun onMapError(exception: Exception?) {
                                    // 필자가 직접 만든 Toast생성 함수
                                    //makeToast(context = context, message = "지도를 불러오는 중 알 수 없는 에러가 발생했습니다.\n onMapError: $exception")
                                }
                            },
                            object : KakaoMapReadyCallback() {
                                // KakaoMap이 준비되었을 때 호출
                                @SuppressLint("UseCompatLoadingForDrawables")
                                override fun onMapReady(kakaoMap: KakaoMap) {
                                    // 카메라를 (locationY, locationX) 위치로 이동시키는 업데이트 생성
                                    val cameraUpdate = CameraUpdateFactory.newCenterPosition(centerPosition)

                                    // 지도에 표시할 라벨의 스타일 설정
                                    var style = kakaoMap.labelManager?.addLabelStyles(LabelStyles.from(LabelStyle.from(R.drawable.ic_home_v1)))
                                    if (!isHome) {
                                        style = kakaoMap.labelManager?.addLabelStyles(LabelStyles.from(LabelStyle.from(R.drawable.ic_medic_v1)))
                                    }
                                    Log.e("", "center ${centerPosition.latitude} ${centerPosition.longitude}")
                                    // 라벨 옵션을 설정하고 위치와 스타일을 적용
                                    val options = LabelOptions.from(centerPosition).setStyles(style)

                                    // KakaoMap의 labelManager에서 레이어를 가져옴
                                    val layer = kakaoMap.labelManager?.layer

                                    // 카메라를 지정된 위치로 이동
                                    kakaoMap.moveCamera(cameraUpdate)

                                    kakaoMap.setOnLodLabelClickListener(object : KakaoMap.OnLodLabelClickListener {
                                        override fun onLodLabelClicked(
                                            kakaoMap: KakaoMap?,
                                            lodLabelLayer: LodLabelLayer?,
                                            lodLabel: LodLabel?
                                        ): Boolean {
                                            lodLabel?.texts?.forEach { it ->
                                                Log.e("", "lodLabel $it, ${it.length}")
                                                clickLabelName = it
                                            }
                                            
                                            return false ;
                                        }
                                    })

                                    // 지도에 라벨을 추가
                                    layer?.addLabel(options)
                                    if (isHome) {
                                        searchKeyList.forEach { item ->
                                            Log.e(
                                                "",
                                                "forEach ... ${item.placeName} ${item.roadAddressName} ${item.y} ${item.x}"
                                            )
                                            val lat = item.y.toDouble()
                                            val lon = item.x.toDouble()
                                            val style = LabelStyles.from(
                                                LabelStyle.from(R.drawable.ic_medic_v1)
                                                    .setTextStyles(30, 0x000000)
                                            )
                                            val labelText =
                                                LabelTextBuilder().setTexts(item.placeName)
                                            val options = LabelOptions.from(LatLng.from(lat, lon))
                                                .setClickable(true)
                                                .setStyles(style).setTexts(labelText)
                                            val lodLayer = kakaoMap.labelManager?.lodLayer
                                            lodLayer?.addLodLabel(options)
                                        }
                                    }
                                }

                                override fun getPosition(): LatLng {
                                    // 현재 위치를 반환
                                    return centerPosition
                                }
                            },
                        )
                    }
                },
            )
    )
}

설명

  1. 프로젝트 설정: build.gradle 파일에 필요한 의존성을 추가합니다.
  2. AndroidView 사용: AndroidView를 사용하여 Compose 내에서 MapView를 렌더링합니다.
  3. 지도 초기화: setMapCenterPointAndZoomLevel을 사용하여 지도 중심점과 줌 레벨을 설정합니다.
  4. LOD 라벨 클릭 이벤트 리스너 설정: setOnLodLabelClickListener를 사용하여 LOD 라벨 클릭 시 위치 정보를 Toast 메시지로 표시합니다.

이 예제를 통해 Jetpack Compose를 사용하여 Kakao Map에서 LOD 라벨을 추가하고 클릭 이벤트를 처리하는 방법을 배울 수 있습니다. 도움이 되셨길 바랍니다! 😊

반응형