From 5c5dfbdd69ec31e4ccd5e3d8988bb9e1b674e009 Mon Sep 17 00:00:00 2001 From: Sungyong An Date: Tue, 19 Nov 2024 22:07:41 +0900 Subject: [PATCH 1/3] Make MapType to pure class to prepare KMP --- .../map/compose/demo/map/LiteModeScreen.kt | 26 +++++++---- .../demo/map/MapTypesAndLayerGroupsScreen.kt | 23 +++++++--- app/src/main/res/values/strings.xml | 17 ------- .../naver/maps/map/compose/MapProperties.kt | 41 ----------------- .../com/naver/maps/map/compose/MapType.kt | 44 +++++++++++++++++++ .../com/naver/maps/map/compose/MapUpdater.kt | 13 ++++++ 6 files changed, 90 insertions(+), 74 deletions(-) create mode 100644 naver-map-compose/src/main/java/com/naver/maps/map/compose/MapType.kt diff --git a/app/src/main/java/com/naver/maps/map/compose/demo/map/LiteModeScreen.kt b/app/src/main/java/com/naver/maps/map/compose/demo/map/LiteModeScreen.kt index 2e8a0329..6b11e52c 100644 --- a/app/src/main/java/com/naver/maps/map/compose/demo/map/LiteModeScreen.kt +++ b/app/src/main/java/com/naver/maps/map/compose/demo/map/LiteModeScreen.kt @@ -37,7 +37,6 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringArrayResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -63,8 +62,15 @@ fun LiteModeScreen(upPress: () -> Unit) { } ) { contentPadding -> Column(modifier = Modifier.padding(contentPadding)) { - val mapTypes = stringArrayResource(R.array.map_types_without_navi) - var selectedPosition by remember { mutableStateOf(0) } + val mapTypes = remember { + listOf( + MapType.Basic, + MapType.Satellite, + MapType.Hybrid, + MapType.Terrain, + ) + } + var selectedMapType by remember { mutableStateOf(MapType.Basic) } Row(verticalAlignment = Alignment.CenterVertically) { Text( @@ -85,9 +91,11 @@ fun LiteModeScreen(upPress: () -> Unit) { verticalAlignment = Alignment.CenterVertically ) { Text( - text = mapTypes[selectedPosition], + text = selectedMapType.toString(), fontSize = 18.sp, - modifier = Modifier.padding(end = 8.dp).weight(1f) + modifier = Modifier + .padding(end = 8.dp) + .weight(1f) ) Icon( Icons.Filled.ArrowDropDown, @@ -98,14 +106,14 @@ fun LiteModeScreen(upPress: () -> Unit) { expanded = expanded, onDismissRequest = { expanded = false } ) { - mapTypes.forEachIndexed { index, mapType -> + mapTypes.forEach { mapType -> DropdownMenuItem( onClick = { expanded = false - selectedPosition = index + selectedMapType = mapType } ) { - Text(text = mapType) + Text(text = mapType.toString()) } } } @@ -124,7 +132,7 @@ fun LiteModeScreen(upPress: () -> Unit) { cameraPositionState = cameraPositionState, properties = MapProperties( isLiteModeEnabled = true, - mapType = MapType.valueOf(mapTypes[selectedPosition]) + mapType = selectedMapType, ), ) } diff --git a/app/src/main/java/com/naver/maps/map/compose/demo/map/MapTypesAndLayerGroupsScreen.kt b/app/src/main/java/com/naver/maps/map/compose/demo/map/MapTypesAndLayerGroupsScreen.kt index e8f09998..ecb0216a 100644 --- a/app/src/main/java/com/naver/maps/map/compose/demo/map/MapTypesAndLayerGroupsScreen.kt +++ b/app/src/main/java/com/naver/maps/map/compose/demo/map/MapTypesAndLayerGroupsScreen.kt @@ -42,7 +42,6 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringArrayResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -68,8 +67,18 @@ fun MapTypesAndLayerGroupsScreen(upPress: () -> Unit) { } ) { contentPadding -> Column(modifier = Modifier.padding(contentPadding)) { - val mapTypes = stringArrayResource(R.array.map_types) - var selectedMapTypePosition by remember { mutableStateOf(0) } + val mapTypes = remember { + listOf( + MapType.Basic, + MapType.Navi, + MapType.Satellite, + MapType.Hybrid, + MapType.NaviHybrid, + MapType.Terrain, + MapType.None, + ) + } + var selectedMapType by remember { mutableStateOf(MapType.Basic) } var isBuildingLayerGroupEnabled by remember { mutableStateOf(true) } var isTransitLayerGroupEnabled by remember { mutableStateOf(false) } @@ -97,7 +106,7 @@ fun MapTypesAndLayerGroupsScreen(upPress: () -> Unit) { verticalAlignment = Alignment.CenterVertically ) { Text( - text = mapTypes[selectedMapTypePosition], + text = selectedMapType.toString(), fontSize = 18.sp, modifier = Modifier.padding(end = 8.dp).weight(1f) ) @@ -114,10 +123,10 @@ fun MapTypesAndLayerGroupsScreen(upPress: () -> Unit) { DropdownMenuItem( onClick = { mapTypeExpanded = false - selectedMapTypePosition = index + selectedMapType = mapType } ) { - Text(text = mapType) + Text(text = mapType.toString()) } } } @@ -235,7 +244,7 @@ fun MapTypesAndLayerGroupsScreen(upPress: () -> Unit) { NaverMap( cameraPositionState = cameraPositionState, properties = MapProperties( - mapType = MapType.valueOf(mapTypes[selectedMapTypePosition]), + mapType = selectedMapType, isBuildingLayerGroupEnabled = isBuildingLayerGroupEnabled, isTransitLayerGroupEnabled = isTransitLayerGroupEnabled, isBicycleLayerGroupEnabled = isBicycleLayerGroupEnabled, diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 497f21ef..4688442f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -285,23 +285,6 @@ Tile Cover Helper 타일 커버 헬퍼 사용 - - Basic - Navi - Satellite - Hybrid - NaviHybrid - Terrain - None - - - - Basic - Satellite - Hybrid - Terrain - - 시스템 설정 사용 한국어(ko-KR) diff --git a/naver-map-compose/src/main/java/com/naver/maps/map/compose/MapProperties.kt b/naver-map-compose/src/main/java/com/naver/maps/map/compose/MapProperties.kt index 951eff3a..a9bde676 100644 --- a/naver-map-compose/src/main/java/com/naver/maps/map/compose/MapProperties.kt +++ b/naver-map-compose/src/main/java/com/naver/maps/map/compose/MapProperties.kt @@ -120,47 +120,6 @@ public data class MapProperties( } } -/** - * 지도의 유형을 나타내는 열거형. - */ -@Immutable -public enum class MapType(public val value: com.naver.maps.map.NaverMap.MapType) { - /** - * 일반 지도. - */ - Basic(com.naver.maps.map.NaverMap.MapType.Basic), - - /** - * 내비게이션 지도. - */ - Navi(com.naver.maps.map.NaverMap.MapType.Navi), - - /** - * 위성 지도. - */ - Satellite(com.naver.maps.map.NaverMap.MapType.Satellite), - - /** - * 위성 지도(겹쳐보기). - */ - Hybrid(com.naver.maps.map.NaverMap.MapType.Hybrid), - - /** - * 내비게이션용 위성 지도(겹쳐보기). - */ - NaviHybrid(com.naver.maps.map.NaverMap.MapType.NaviHybrid), - - /** - * 지형도. - */ - Terrain(com.naver.maps.map.NaverMap.MapType.Terrain), - - /** - * 없음. 지도는 나타나지 않고 오버레이만이 나타납니다. - */ - None(com.naver.maps.map.NaverMap.MapType.None) -} - /** * 위치 추적 모드를 나타내는 열거형. */ diff --git a/naver-map-compose/src/main/java/com/naver/maps/map/compose/MapType.kt b/naver-map-compose/src/main/java/com/naver/maps/map/compose/MapType.kt new file mode 100644 index 00000000..b4fb374b --- /dev/null +++ b/naver-map-compose/src/main/java/com/naver/maps/map/compose/MapType.kt @@ -0,0 +1,44 @@ +package com.naver.maps.map.compose + +import androidx.compose.runtime.Immutable + +/** + * 지도의 유형을 나타내는 열거형. + */ +@Immutable +public sealed interface MapType { + /** + * 일반 지도. + */ + public data object Basic : MapType + + /** + * 내비게이션 지도. + */ + public data object Navi : MapType + + /** + * 위성 지도. + */ + public data object Satellite : MapType + + /** + * 위성 지도(겹쳐보기). + */ + public data object Hybrid : MapType + + /** + * 내비게이션용 위성 지도(겹쳐보기). + */ + public data object NaviHybrid : MapType + + /** + * 지형도. + */ + public data object Terrain : MapType + + /** + * 없음. 지도는 나타나지 않고 오버레이만이 나타납니다. + */ + public data object None : MapType +} diff --git a/naver-map-compose/src/main/java/com/naver/maps/map/compose/MapUpdater.kt b/naver-map-compose/src/main/java/com/naver/maps/map/compose/MapUpdater.kt index 192d2005..d9c4e908 100644 --- a/naver-map-compose/src/main/java/com/naver/maps/map/compose/MapUpdater.kt +++ b/naver-map-compose/src/main/java/com/naver/maps/map/compose/MapUpdater.kt @@ -27,6 +27,8 @@ import androidx.compose.ui.unit.LayoutDirection import com.naver.maps.map.LocationSource import com.naver.maps.map.NaverMap import java.util.Locale +import com.naver.maps.map.NaverMap.MapType as NaverMapType +import com.naver.maps.map.compose.MapType as ComposeMapType internal class MapPropertiesNode( val map: NaverMap, @@ -203,3 +205,14 @@ internal inline fun MapUpdater( set(mapProperties.locationTrackingMode) { map.locationTrackingMode = it.value } } } + +private val ComposeMapType.value: NaverMapType + get() = when (this) { + ComposeMapType.Basic -> NaverMapType.Basic + ComposeMapType.Navi -> NaverMapType.Navi + ComposeMapType.Satellite -> NaverMapType.Satellite + ComposeMapType.Hybrid -> NaverMapType.Hybrid + ComposeMapType.NaviHybrid -> NaverMapType.NaviHybrid + ComposeMapType.Terrain -> NaverMapType.Terrain + ComposeMapType.None -> NaverMapType.None + } From 1da20fdbbd7a3ba509d4b13a782ad8643f0cb4d5 Mon Sep 17 00:00:00 2001 From: Sungyong An Date: Wed, 20 Nov 2024 01:17:04 +0900 Subject: [PATCH 2/3] Add test codes to compare --- gradle/libs.versions.toml | 4 ++- naver-map-compose/build.gradle | 2 ++ .../naver/maps/map/compose/ClassTestUtil.kt | 23 ++++++++++++++++ ...mpleInstrumentedTest.kt => MapTypeTest.kt} | 27 ++++++++++--------- .../com/naver/maps/map/compose/MapType.kt | 15 +++++++++++ 5 files changed, 57 insertions(+), 14 deletions(-) create mode 100644 naver-map-compose/src/androidTest/java/com/naver/maps/map/compose/ClassTestUtil.kt rename naver-map-compose/src/androidTest/java/com/naver/maps/map/compose/{ExampleInstrumentedTest.kt => MapTypeTest.kt} (55%) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d771cae5..00153358 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -34,6 +34,8 @@ google-play-services-location = { module = "com.google.android.gms:play-services kotlin-pluginGradle = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } +kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } +kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" } dokka-pluginGradle = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "dokka" } @@ -60,6 +62,6 @@ androidx-profileinstaller = "androidx.profileinstaller:profileinstaller:1.2.0" # Test -androidx-test-ext-junit = "androidx.test.ext:junit:1.1.3" +androidx-test-ext-junit = "androidx.test.ext:junit:1.2.1" androidx-test-espresso-core = "androidx.test.espresso:espresso-core:3.4.0" androidx-test-uiautomator = "androidx.test.uiautomator:uiautomator:2.2.0" diff --git a/naver-map-compose/build.gradle b/naver-map-compose/build.gradle index fb1924ca..5007ce71 100644 --- a/naver-map-compose/build.gradle +++ b/naver-map-compose/build.gradle @@ -48,6 +48,8 @@ dependencies { implementation libs.google.play.services.location implementation libs.accompanist.permissions + androidTestImplementation libs.kotlin.test + androidTestImplementation libs.kotlin.reflect androidTestImplementation libs.androidx.test.ext.junit androidTestImplementation libs.androidx.test.espresso.core } diff --git a/naver-map-compose/src/androidTest/java/com/naver/maps/map/compose/ClassTestUtil.kt b/naver-map-compose/src/androidTest/java/com/naver/maps/map/compose/ClassTestUtil.kt new file mode 100644 index 00000000..3b443009 --- /dev/null +++ b/naver-map-compose/src/androidTest/java/com/naver/maps/map/compose/ClassTestUtil.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2024 SOUP + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.naver.maps.map.compose + +/** + * The list of the immediate subclasses if this class is a sealed class, or an empty list otherwise. + */ +internal inline fun sealedSubclasses(): List { + return T::class.sealedSubclasses.mapNotNull { it.objectInstance } +} diff --git a/naver-map-compose/src/androidTest/java/com/naver/maps/map/compose/ExampleInstrumentedTest.kt b/naver-map-compose/src/androidTest/java/com/naver/maps/map/compose/MapTypeTest.kt similarity index 55% rename from naver-map-compose/src/androidTest/java/com/naver/maps/map/compose/ExampleInstrumentedTest.kt rename to naver-map-compose/src/androidTest/java/com/naver/maps/map/compose/MapTypeTest.kt index a04d083a..9f22b476 100644 --- a/naver-map-compose/src/androidTest/java/com/naver/maps/map/compose/ExampleInstrumentedTest.kt +++ b/naver-map-compose/src/androidTest/java/com/naver/maps/map/compose/MapTypeTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2022 SOUP + * Copyright 2024 SOUP * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,22 +16,23 @@ package com.naver.maps.map.compose import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.platform.app.InstrumentationRegistry -import org.junit.Assert.assertEquals import org.junit.Test import org.junit.runner.RunWith +import kotlin.test.assertEquals +import com.naver.maps.map.NaverMap.MapType as NaverMapType +import com.naver.maps.map.compose.MapType as ComposeMapType -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ @RunWith(AndroidJUnit4::class) -internal class ExampleInstrumentedTest { +internal class MapTypeTest { + @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("com.naver.maps.map.compose.test", appContext.packageName) + fun equals() { + val naverMapTypes = NaverMapType.entries.map { it.name }.sorted() + val composeMapTypes = sealedSubclasses().map { it.toString() }.sorted() + assertEquals( + expected = naverMapTypes, + actual = composeMapTypes, + message = "The MapType class of NaverMap SDK and naver-map-compose do not match exactly.", + ) } } diff --git a/naver-map-compose/src/main/java/com/naver/maps/map/compose/MapType.kt b/naver-map-compose/src/main/java/com/naver/maps/map/compose/MapType.kt index b4fb374b..953e6471 100644 --- a/naver-map-compose/src/main/java/com/naver/maps/map/compose/MapType.kt +++ b/naver-map-compose/src/main/java/com/naver/maps/map/compose/MapType.kt @@ -1,3 +1,18 @@ +/* + * Copyright 2024 SOUP + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.naver.maps.map.compose import androidx.compose.runtime.Immutable From 2141f4170da353f7fb1c2e479b2e0474a9be3045 Mon Sep 17 00:00:00 2001 From: Sungyong An Date: Wed, 20 Nov 2024 01:24:53 +0900 Subject: [PATCH 3/3] generate metalava --- naver-map-compose/api/current.api | 41 ++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/naver-map-compose/api/current.api b/naver-map-compose/api/current.api index 3b2baca8..b0cf5808 100644 --- a/naver-map-compose/api/current.api +++ b/naver-map-compose/api/current.api @@ -282,18 +282,35 @@ package com.naver.maps.map.compose { property public final float symbolScale; } - @androidx.compose.runtime.Immutable public enum MapType { - method public final com.naver.maps.map.NaverMap.MapType! getValue(); - method public static com.naver.maps.map.compose.MapType valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException; - method public static com.naver.maps.map.compose.MapType[] values(); - property public final com.naver.maps.map.NaverMap.MapType! value; - enum_constant public static final com.naver.maps.map.compose.MapType Basic; - enum_constant public static final com.naver.maps.map.compose.MapType Hybrid; - enum_constant public static final com.naver.maps.map.compose.MapType Navi; - enum_constant public static final com.naver.maps.map.compose.MapType NaviHybrid; - enum_constant public static final com.naver.maps.map.compose.MapType None; - enum_constant public static final com.naver.maps.map.compose.MapType Satellite; - enum_constant public static final com.naver.maps.map.compose.MapType Terrain; + @androidx.compose.runtime.Immutable public sealed interface MapType { + } + + public static final class MapType.Basic implements com.naver.maps.map.compose.MapType { + field public static final com.naver.maps.map.compose.MapType.Basic INSTANCE; + } + + public static final class MapType.Hybrid implements com.naver.maps.map.compose.MapType { + field public static final com.naver.maps.map.compose.MapType.Hybrid INSTANCE; + } + + public static final class MapType.Navi implements com.naver.maps.map.compose.MapType { + field public static final com.naver.maps.map.compose.MapType.Navi INSTANCE; + } + + public static final class MapType.NaviHybrid implements com.naver.maps.map.compose.MapType { + field public static final com.naver.maps.map.compose.MapType.NaviHybrid INSTANCE; + } + + public static final class MapType.None implements com.naver.maps.map.compose.MapType { + field public static final com.naver.maps.map.compose.MapType.None INSTANCE; + } + + public static final class MapType.Satellite implements com.naver.maps.map.compose.MapType { + field public static final com.naver.maps.map.compose.MapType.Satellite INSTANCE; + } + + public static final class MapType.Terrain implements com.naver.maps.map.compose.MapType { + field public static final com.naver.maps.map.compose.MapType.Terrain INSTANCE; } public final class MapUiSettings {