シンプルな画面遷移の実装録です。
参考
TODO
- Routeの定義
- NavControllerの作成
- NavHostの作成
- 画面遷移の実装
Setup
- Navigation Composeの導入
- Serialization の導入
libs.versitions.toml
[versions]
navigationCompose = "2.8.5"
kotlinSerialization = "1.9.0"
[libraries]
androidx-navigation-compose = {group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose"}
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }
[plugins]
kotlinx-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlinSerialization" }
Routeの定義
- ルートを型で表現することで、存在しない画面への遷移ミスを防ぐ
- 内部的にはルートを文字列として扱っているためシリアライズ処理が必要
App.kt
object Route {
@Serializable
data object FirstPage
@Serializable
data object SecondPage
@Serializable
data object ThirdPage
}
NavControllerの作成
- rememberNavController()を使う
- fun App()の引数など、Composable 階層の高い位置で作成する、これはすべての画面ここを参照して画面遷移するため
- 状態をより高位のComposableで管理する状態ホイスティングの考え方を使う
App.kt
@Composable
fun App(
navController: NavHostController = rememberNavController()
) {
// code //
}
NavHostの作成
- NavHostの役割は、バックスタック最上位の画面表示と、ナビゲーショングラフの定義
- 引数のnavControllerに先ほど定義したnavControllerを、startDestinationにナビゲーショングラフの起点となるルートを設定する
- ナビゲーショングラフの実態はNavHostのラムダ内で定義する(composable<ルート>)
App.kt
@Composable
fun App(
navController: NavHostController = rememberNavController()
) {
NavHost(
navController = navController,
startDestination = Route.FirstScreen
) {
composable<Route.FirstPage> { FirstScreen(
onNavigateToSecondScreen = { navController.navigate(Route.SecondPage) }
) }
composable<Route.SecondPage> { SecondScreen(
onNavigateToThirdScreen = { navController.navigate(Route.ThirdPage) }
) }
composable<Route.ThirdPage> { ThirdScreen(
onNavigateToThirdScreen = { navController.navigate(Route.ThirdPage) }
) }
}
}
画面遷移の実装
FirstScreen.kt
@Composable
fun FirstScreen(
onNavigateToSecondScreen: () -> Unit
) {
Scaffold(
bottomBar = {
BottomAppBar(
containerColor = MaterialTheme.colorScheme.primaryContainer,
contentColor = MaterialTheme.colorScheme.primary,
) {
Text(
modifier = Modifier
.fillMaxWidth(),
textAlign = TextAlign.Center,
text = "Bottom app bar",
)
}
},
) { innerPadding ->
Column(
modifier = Modifier
.padding(innerPadding),
) {
Image(
painter = painterResource(id = R.drawable.sample_icon),
contentDescription = "サンプルアイコン",
Modifier.clickable { onNavigateToSecondScreen() } // タップ時にラムダを実行してイベントを通知
)
}
}
}
補足
状態ホイスティングとは
状態を定義する場所を上位のコンポーザブルに移動することを状態ホイスティングと呼びます。上位のコンポーザブルから下位のコンポーザブルに状態を渡し、下位のコンポーザブルから上位のコンポーザブルにイベントを渡します。
これにより状態を一元管理することができます。