์๋ก
์ด๋ฒ์ compose ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉด์ ํ๋ฉด ์ด๋ ์ ์ธ์๋ฅผ ์ ๋ฌํ๋ safe args๋ฅผ ๋ค์ ์ฌ์ฉํ๊ฒ ๋์๋๋ฐ, safe args๊ฐ ์ด๋ฒ compose ์ต์ ์ ๋ฐ์ดํธ๋ก ๋ ํธ๋ฆฌํ๊ฒ ๊ตฌํํ ์ ์๋๋ก ๋ณ๊ฒฝ๋ ๊ฒ ๊ฐ์์ ์ด๋ฒ ๊ธฐํ์ ์ด๋ป๊ฒ ๊ตฌํํ๋์ง ์ ๋ฆฌํด ๋ณด๋ ค ํ๋ค.
Navigation 2.8.0์ safe args ๋ณ๊ฒฝ ์ฌํญ
์ด๋ฒ์ Navigation์ ๋ฒ์ ์ด 2.8.0-alpha08 ๋ฒ์ ์ผ๋ก ์ ๊ทธ๋ ์ด๋๋๋ฉด์ kotlin์ Serializable์ ํตํด ์ธ์๋ฅผ ๋๊ธธ ์ ์๊ฒ ๋ณ๊ฒฝ๋์๋ค.
Serializable์ ํตํด data class๋ก ํ๋ฉด์ ์ ์ํ๊ณ data class์ ํ๋๋ก ๊ฐ์ ์ ๋ฌํ ์ ์๋ค.
๊ทธ๋ฌ๋ฉด ๋ฐ๋ก ์ด๋ป๊ฒ ๊ตฌํํ๋์ง ์์๋ณด์.
Serializable, Navigation ์ถ๊ฐ
libs.versions.toml์ ์ถ๊ฐ ํ gradle ํ์ผ์ ์ ์ฉํ์(2025.01.23 ๊ธฐ์ค ์ต์ navigation ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฒ์ : 2.8.5)
kotlin = "2.0.21"
navigationCompose = "2.8.5"
[libraries]
androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigationCompose" }
[plugins]
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
build.gradle.kts(project)
alias(libs.plugins.kotlin.serialization) apply false
build.gradle.kts(app)
plugins {
alias(libs.plugins.kotlin.serialization)
}
dependencies {
// navigation compose
implementation(libs.androidx.navigation.compose)
implementation(libs.kotlinx.serialization.json)
}
Navigation ๊ตฌํ
์ฐ์ ํ๋ฉด์ ๋จผ์ ์์ฑํ๋ค.
ํ๋ฉด๋ค์ sealed class๋ฅผ ํตํด ์ ์ํ๋ค.
sealed class Screen {
@Serializable
data object LoginScreen: Screen()
@Serializable
data object MainScreen: Screen()
@Serializable
data class ProfileScreen(val id: Int): Screen()
}
Serializable ์ด๋ ธํ ์ด์ ์ ํ๋ฉด๋ง๋ค ํ์์ ์ผ๋ก ๋ฌ์์ค์ผ ํ๋ค.
๋ค์์ผ๋ก ์์ฑํ Screen์ ํตํด NavHost๋ฅผ ๋ง๋ค๊ณ MainActivity์ ์ ์ฉํ๋ค.
@Composable
fun Navigation(modifier: Modifier = Modifier) {
val navController = rememberNavController()
NavHost(
modifier = modifier,
navController = navController,
startDestination = Screen.LoginScreen
) {
composable<Screen.LoginScreen> {
LoginScreen(
...
)
}
composable<Screen.MainScreen> {
MainScreen(
...
)
}
composable<Screen.ProfileScreen> { backStackEntry ->
ProfileScreen(
...
)
}
}
}
์ฌ๊ธฐ๊น์ง๊ฐ ๊ธฐ๋ณธ์ ์ธ Navigation ์ธํ ๋ฐฉ๋ฒ์ด๋ค.
๋ค๋ฅธ Screen์ผ๋ก ์ธ์ ์ ๋ฌํ๊ธฐ
์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก ์ธ์๋ฅผ ์ ๋ฌํด ๋ณด๊ฒ ๋ค.
Screen ํ์ผ์์๋ ํ์ธํ๋ค์ํผ, ProfileScreen์ id๋ผ๋ ํ๋๊ฐ ์๋ค.
์ ํ๋๋ก ์ค์ ProfileScreen์์ id๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ๋๋ค.
MainScreen์์ ProfileScreen์ผ๋ก id ์ธ์๋ฅผ ์ ๋ฌํ๋ ค๊ณ ํ ๋๋ฅผ ์๋ก ๋ค์ด์ ๊ตฌํํ๋ค.
MainScreen์ด ์ ๋ฌํ๋ ์ชฝ์ด๊ณ , ProfileScreen์ด ์ ๋ฌ๋ฐ์ ์ธ์๋ฅผ ๋ฐ๋ ์ชฝ์ด ๋๋ค.
๋ค์ NavHost๋ก ๋์์์, ์ ๋ฌํ๋ ์ชฝ์์๋ ์ด๋์ํฌ Screen์ ์ ์ํ๊ฒ ๋๋๋ฐ ์ด๋ ์ด๋์ํฌ Screen์ data class ํํ์ด์ด์ผ ํ๋ค.
MainScreen(
navigateToLogin = {
navController.popBackStack()
},
navigateToProfile = {
navController.navigate(Screen.ProfileScreen(it))
}
)
navigateToProfile์์ Screen.ProfileScreen์ผ๋ก navigate ํ๋ฉด์ ์ธ์๋ฅผ ์ ๋ฌํด์ผ ํ๋ค.
์ธ์๋ MainScreen์์ ๋ฐ์์ ๊ณ ์ฐจ ํจ์๋ก ์ ๋ฌํด ์ฃผ๋ฉด ๋๋ค.
์ด์ ๋ฐ๋ ์ชฝ์์๋ ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํด์ผ ํ๊ธฐ ๋๋ฌธ์ ์์ ์ Screen ์ ๋ณด๋ฅผ ํ์ ์ผ๋ก ๊ฐ์ง๋ ๋งค๊ฐ๋ณ์๋ฅผ ํ๋ ์ถ๊ฐํด ์ฃผ์ด์ผ ํ๋ค.
@Composable
fun ProfileScreen(
navigateToMain: () -> Unit,
args: Screen.ProfileScreen
) {
...
}
๊ทธ๋ฆฌ๊ณ NavHost ์ชฝ์์๋ ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ args๋ก ๋๊ฒจ์ฃผ๋ ์์ ์ ์งํํ๊ธฐ ์ํด ๋ค์๊ณผ ๊ฐ์ด ์ฝ๋๋ฅผ ์์ฑํ๋ค.
composable<Screen.ProfileScreen> { backStackEntry ->
ProfileScreen(
navigateToMain = {
navController.popBackStack()
},
args = backStackEntry.toRoute<Screen.ProfileScreen>()
)
}
์ด๋ ๊ฒ ํ๋ฉด ๊ตฌํ์ด ๋๋๋ค. ํจ์ฌ ๊ฐ๋จํ์ง ์์๊ฐ?
๊ธฐ์กด์ ๋ฐฉ์๊ณผ ๋ณ๊ฒฝ๋ ์
๊ธฐ์กด์ ๋ฐฉ์์ ๋ฌธ์์ด์ ๋๊ฒจ์ ํ์ ์ผ๋ก ๋ณํํ๋ ๊ณผ์ ์ ๊ฑฐ์ณค์๋ค.
๊ทธ๋ฆฌ๊ณ route๋ก ๋ฌธ์์ด์ ๋๊ธฐ๋ ๋์ ์ data class๋ฅผ ์ด์ฉํด serializable ๊ฐ์ฒด๋ฅผ ๋๊ธด๋ค.
์ 2๊ฐ์ง๋ง ๋ด๋ ์ฝ๋์ ์๋ ์ค์ด๋ค๊ณ ๊ฐ๋ ์ฑ์ด ํฅ์๋ ๊ฒ์ด ์ฒด๊ฐ๋์๋ค.
์๋ก์์ง navigation compose safe args๋ฅผ ์ฌ์ฉํ๋ฉด ํ๋ฉด๋ผ๋ฆฌ ๊ณต์ ๋๋ ๋ฐ์ดํฐ ๊ด๋ฆฌ๊ฐ ํจ์ฌ ์์ํด์ง ๋ฏํ๋ค.
'๐ฑ| Android > ๐ | Jetpack' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Android, Kotlin] Compose์์ glance๋ฅผ ์ด์ฉํด ์์ ฏ ๋ง๋ค๊ธฐ (0) | 2023.10.06 |
---|---|
[Android, Kotlin] jetpack navigation์์ safe args๋ก ๋ฐ์ดํฐ ์ ๋ฌํ๊ธฐ (0) | 2023.09.26 |
[Android, Kotlin] compose custom theme ๋ง๋ค๊ธฐ (0) | 2023.08.18 |
[Android, Kotlin] compose๋ก custom checkbox ๋ง๋ค๊ธฐ (0) | 2023.08.18 |
[Android, Kotlin] compose๋ก tablayout ๊ตฌํํ๊ธฐ (2) | 2023.08.15 |