
🤔 Navigation Graph はもう navigation() だけじゃない
Jetpack Compose 向けの Navigation 3 では、従来の Navigation Component にあった navigation() を使ったネストした Navigation Graph の考え方がなくなりました。
その代わりに、「コードをどう整理するか」と「BackStack をどう分けるか」を分離して考える設計になっています。
この記事では、Navigation 3 でよく使われる 3 つの Navigation Graph パターンを紹介します。
🤔 Navigation 3 の3つのパターン
Navigation 3
│
├─ コードを整理したい
│ ├─ Extension Functions
│ └─ Sealed NavKeys
│
└─ BackStack を分けたい
└─ Nested NavDisplay
ポイントは、
- コードを整理する方法
- BackStack を分離する方法
は別の話だということです。
🤔 Extension Functions で画面を機能ごとに分割する
Navigation 3 では entry() を並べて画面を登録します。
画面数が増えてくると、1つのファイルに全部書くのは見づらくなります。
そんなときは Extension Function へ切り出すのが最もシンプルです。
// AuthModule.kt
fun EntryProviderScope<NavKey>.authGraph() {
entry<Login> {
LoginScreen()
}
entry<SignUp> {
SignUpScreen()
}
}
メイン側では呼び出すだけです。
val entryProvider = entryProvider {
authGraph()
entry<Home> {
HomeScreen()
}
}
NavDisplay(
backStack = backStack,
entryProvider = entryProvider
)
これだけで認証画面を別ファイルへ分離できます。
メリット
- Feature 単位で管理できる
- モジュール分割しやすい
- BackStack は1つなので構成はシンプル
🤔 Sealed NavKey で画面をグループ化する
もう1つの整理方法が NavKey をグループ化する 方法です。
sealed interface AuthKey : NavKey {
@Serializable
data object Login : AuthKey
@Serializable
data object SignUp : AuthKey
}
sealed interface MainKey : NavKey {
@Serializable
data object Home : MainKey
@Serializable
data class Detail(
val id: String
) : MainKey
}
画面遷移も名前空間付きで分かりやすくなります。
Navigation 3 では Graph は存在しませんが、
- Auth 系
- Main 系
- Settings 系
のように論理的に整理できます。
メリット
- 名前空間が分かりやすい
- 型安全
- Destination が探しやすい
🤔 NavDisplay をネストする
ここだけは少し意味が変わります。
これはコード整理ではなく BackStack を分離する方法です。
例えば
- Bottom Navigation
- タブ
- Onboarding
- 独立したフロー
では、それぞれ独自の履歴を持たせたいことがあります。
その場合は NavDisplay をネストします。
entry<MainTabs> {
MainTabsScreen()
}
@Composable
fun MainTabsScreen() {
val tabBackStack =
rememberNavBackStack(HomeTab)
NavDisplay(
backStack = tabBackStack,
entryProvider = entryProvider {
entry<HomeTab> {
HomeScreen()
}
entry<SearchTab> {
SearchScreen()
}
entry<ProfileTab> {
ProfileScreen()
}
}
)
}
ここでは親とは別の NavBackStack を持っています。
Root
NavDisplay
│
└── MainTabs
│
└── NavDisplay
│
├── Home
├── Search
└── Profile
つまり、
NavDisplay = NavBackStack の管理単位
という考え方になります。
Bottom Navigation で各タブの履歴を保持できるのも、この仕組みによるものです。
🤔 どれを選べばいい?
次のように考えると分かりやすいでしょう。
画面を整理したい?
│
├─ Yes
│ ├─ Extension Functions
│ └─ Sealed NavKeys
│
└─ BackStack を分けたい?
└─ Nested NavDisplay

🤔 まとめ
Navigation 3 では、従来の navigation() による Graph のネストはありません。
その代わりに、
- Extension Functions で entry() を機能ごとに分割する
- Sealed NavKey で Destination を整理する
- Nested NavDisplay で独立した NavBackStack を持つ
という3つのパターンを組み合わせて設計します。
特に重要なのは、コードの整理と BackStack の分離は別の概念という点です。
Navigation 3 は Graph をネストするライブラリではなく、NavDisplay と NavBackStack を組み合わせてナビゲーション構造を組み立てるライブラリへと進化しています。
🤔 参考
Related Categories : Android・Developmemt・JetpackCompose・KMP・Kotlin・Kotlin Multiplatform Mobile・Trending