반응형
아이나비 맵 SDK Compose로 사용해보기
아이나비 맵 SDK는 컴포즈 버전이 따로 존재하지 않고 xml로 되어있는 layout을 이용하거나 Fragment 인스턴스를 이용해서 사용해야한다.
해당 작업을 진행하고 나면 아이나비 맵뿐만 아니라 다른 지도 sdk도 compose를 이용하여 작성할 수 있을 것이라고 생각한다.
1안 xml layout을 이용하여 AndroidView로 Wrapping
@Composable
fun InaviMapUsingXmlView(
modifier: Modifier = Modifier,
) {
val context = LocalContext.current
AndroidView(
modifier = modifier.fillMaxSize(),
factory = {
FragmentContainerView(context).apply {
id = R.id.map_fragment
}
},
update = {
val fragmentManager = (context as FragmentActivity).supportFragmentManager
fragmentManager.beginTransaction().replace(R.id.map_fragment, InvMapFragment()).commit()
}
)
}
InaviMapUsingXmlView.kt
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/map_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.inavi.mapsdk.maps.InvMapFragment" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
fragment_map.xml
- layout을 통해 FragmentContainerView를 이용할 수 있도록 구현
- 문제점
- 특정 상황에서 Composable NavigationBar를 사용하게 되면 Map이 commit되지 않는 상태 발생
- 해당 상태를 처리해줘야함
2안 InvMapView를 AndroidView로 Wrapping
@Composable
fun InaviMapUsingCompose(
modifier: Modifier = Modifier,
invMapOptions: InvMapOptions? = null,
onMapReady: (map: InaviMap?) -> Unit
) {
val mapView = rememberMapViewWithLifecycle(
invMapOptions = invMapOptions,
onMapReady = onMapReady
)
AndroidView(
modifier = modifier.fillMaxSize(),
factory = { mapView },
update = {
}
)
}
@Composable
private fun rememberMapViewWithLifecycle(
invMapOptions: InvMapOptions? = null,
onMapReady: (map: InaviMap?) -> Unit,
): InvMapView {
val context = LocalContext.current
val mapView = remember {
InvMapView(context, invMapOptions).apply {
getMapAsync(OnMapReadyCallback(onMapReady))
}
}
val lifecycleObserver = rememberMapLifecycleObserver(mapView = mapView)
val lifecycle = LocalLifecycleOwner.current.lifecycle
DisposableEffect(lifecycle) {
lifecycle.addObserver(lifecycleObserver)
onDispose {
lifecycle.removeObserver(lifecycleObserver)
}
}
return mapView
}
@Composable
private fun rememberMapLifecycleObserver(mapView: InvMapView): LifecycleEventObserver = remember {
LifecycleEventObserver { _, event ->
when (event) {
Lifecycle.Event.ON_CREATE -> mapView.onCreate(Bundle())
Lifecycle.Event.ON_START -> mapView.onStart()
Lifecycle.Event.ON_RESUME -> mapView.onResume()
Lifecycle.Event.ON_PAUSE -> mapView.onPause()
Lifecycle.Event.ON_STOP -> mapView.onStop()
Lifecycle.Event.ON_DESTROY -> mapView.onDestroy()
else -> throw IllegalStateException()
}
}
}
InaviMapUsingCompose.kt
- LifecycleEventObserver를 이용하여 InvMapView에 lifecycle에 해당하는 이벤트를 발생시킬 수 있도록 설정
- AndroidView에 MapView Wrapping
참고자료
https://github.com/inavi-systems/inavi-maps-demo-android
반응형
'Android > Compose' 카테고리의 다른 글
Compose Multiplatform - shadow open source contribute 도전기 (5) | 2024.11.17 |
---|---|
Orbit 없이 MVI 패턴 적용기 (0) | 2024.09.08 |
[안드로이드] Inner Shadow, Drop Shadow 처리하는 방법 (1) | 2024.06.10 |
[안드로이드] Jetpack Compose UI Test 맛보기 (0) | 2024.05.12 |
[안드로이드] Compose 밑줄 텍스트와 클릭 가능하게 만들기 (0) | 2024.05.04 |