Navigation Compose:概要、アーキテクチャ、開発における役割

著者: IT Sectr 公開日: 2026-06-29 読了時間: 8 分

Navigation Composeは、Jetpack Composeで構築されたAndroidアプリケーション内部での宣言的ナビゲーションのためのJetpackライブラリです。FragmentManagerやIntentベースのナビゲーションの代わりに、Navigation ComposeはNavControllerNavHostを介して管理される単一のルートグラフを提供します。Google I/O(2025)によると、Navigation ComposeはComposeアプリケーションの推奨ナビゲーション方法であり、新規プロジェクトの70%以上で使用されています。このライブラリは、型指定された引数の受け渡し、ディープリンク、トランジションアニメーション、SavedStateHandleを介したViewModelとの統合をサポートしています。

重要ポイント

  • Navigation Compose — 統一されたルートグラフを持つComposeでの宣言的ナビゲーションのためのJetpackライブラリ
  • NavController — ナビゲーションスタックとバックスタックの状態を管理する中央コントローラー
  • NavHost — ルート付きのcomposable関数を介してルートグラフを定義するコンテナ
  • 引数は、型指定されたパラメーターサポート付きでNavTypeとSavedStateHandleを介して渡されます
  • ディープリンク — URIからの自動引数解析を伴う外部URLを介したナビゲーション

Navigation Composeとは?

Navigation Composeは、Composeアプリケーションにナビゲーションフレームワークを提供するJetpackスイートのライブラリです。このライブラリはViewシステム用のNavigation Componentと同じ原理に基づいていますが、Composeの宣言的な性質に適応しています。FragmentTransactionの代わりにcomposable関数が使用され、ナビゲーショングラフはKotlin DSLを介して構築されます。

Navigation Composeと従来のナビゲーションの主な違いは、FragmentManagerが不要なことです。各画面はcomposable関数であり、ルートが一致するとNavHostでレンダリングされます。バックスタックはFragmentではなく、ルート、引数、状態を含むレコードを保存します。これによりアーキテクチャが簡素化され、Fragmentベースのナビゲーションに特有のライフサイクルの競合が排除されます。

Google(2025)によると、Navigation Composeは実験段階から安定版へと移行し、バージョン2.8.0以降Jetpackの一部となっています。このライブラリはMaterial3、型安全ナビゲーション(Kotlin Serialization経由)、ネストされたグラフ、モジュール化をサポートしています。唯一の制限は、手動設定なしではBottomNavigationのマルチバックスタックをサポートしていないことですが、Googleはこれに取り組んでいます。

Navigation Composeのアーキテクチャは3つのエンティティを中心に構成されています。NavController(スタック管理)、NavHost(グラフコンテナ)、NavDestination(composableを持つ個別のルート)です。それらの間の相互作用は宣言的です。開発者がルートと引数を記述し、ライブラリが読み込み、保存、復元の状態を処理します。

NavControllerはNavigation Composeの中心的な要素であり、ナビゲーションスタックを管理します。rememberNavController()を介して作成され、NavHostに渡されます。NavControllerはバックスタック、現在のエントリポイントを保存し、遅延アクション(グラフ初期化後のディープリンク)をサポートします。

kotlin
@Composable
fun AppNavigation() {
    val navController = rememberNavController()
    NavHost(navController = navController, startDestination = "home") {
        composable("home") { HomeScreen(navController) }
        composable("profile/{userId}") { backStackEntry ->
            ProfileScreen(
                userId = backStackEntry.arguments?.getString("userId") ?: ""
            )
        }
    }
}

NavControllerの主要メソッド:navigate(route) — ルートに移動、popBackStack() — 前の画面に戻る、navigateAndClear(route) — スタックをクリアして移動。NavOptionsは動作を指定します:launchSingleTopは重複を防止、popUpToは指定されたルートまでスタックをクリア、restoreStateは以前の状態を復元します。

深くネストされたcomposable関数からNavControllerにアクセスするには、CompositionLocalを介してNavHostControllerを使用します。LocalNavControllerはNavHost内のScopedNavControllerで提供されます。NavHostの外側(例:BottomNavigation)では、コントローラーはパラメーターまたはViewModelを介して渡されます。

NavHostは、NavControllerをルートグラフに結び付けるcomposableコンテナです。各ルートはcomposable(route, arguments, deepLinks)を介して宣言されます。ここでrouteは、オプションの{param}プレースホルダーを持つルート文字列です。現在のルートが一致すると、NavHostは対応するcomposableブロックをレンダリングします。

ルートグラフは階層的に構築されます。モジュール内でルートをグループ化するために、navigation()を介してグラフをネストできます。ネストされたグラフは独自のstartDestinationを持ち、共通のルートプレフィックスの下で結合されます。これにより、各機能モジュールが独自のサブグラフを登録するモジュラーアーキテクチャを編成できます。

kotlin
NavHost(
    navController = navController,
    startDestination = "main"
) {
    composable("main") { MainScreen(navController) }
    navigation(
        route = "auth",
        startDestination = "auth/login"
    ) {
        composable("auth/login") { LoginScreen(navController) }
        composable("auth/register") { RegisterScreen(navController) }
    }
}

NavHostはLocalBackDispatcherを介してシステムの戻るボタン(バックプレス)を自動的に処理します。Material3 Scaffoldでは、デフォルトでNavControllerを取得してBottomNavigationを正しく動作させます。NavHostはルートが変更されるとcomposableを再作成しますが、rememberSaveableを介して入力フィールドとスクロールの状態を保持します。

画面間での引数の受け渡し

Navigation Composeは、ルートパラメーターとNavTypeを介して画面間での型指定された引数の受け渡しをサポートしています。パラメーターはルート内で{paramName}として指定され、composable()のargumentsを介して型が指定されます。NavTypeはString、Int、Long、Float、Boolean、Parcelable、Serializableをサポートしています。

引数の型NavTypeルートの例
StringNavType.StringType"profile/{name}"
IntNavType.IntType"item/{id}"
BooleanNavType.BoolType"settings?enabled={flag}"
ParcelableNavType.ParcelableType"details/{item}"
FloatNavType.FloatType"map?lat={lat}&lng={lng}"

引数はNavBackStackEntryからarguments?.getType(key)を介して抽出されます。必須パラメーターにはdefaultValueを使用し、オプションのパラメーターにはnullableを使用します。ParcelableのサポートはKotlin Parcelizeまたはkotlinx.parcelizeライブラリでのみ機能します。複雑なオブジェクトの場合は、オブジェクト全体をシリアライズするのではなく、IDを渡してViewModelを介してデータをロードすることをお勧めします。

Navigation 2.8.0以降、Kotlin Serializationを使用した型安全ナビゲーションが導入されました。ルートはデータクラスとして定義され、引数はフィールドとして定義されます。これにより、文字列ルートが型指定されたオブジェクトに置き換えられ、ルート名のエラーが排除されます。移行にはKotlin Serializationプラグインとnavigation-compose-typesafe依存関係が必要です。

kotlin
@Serializable
/* sealed class Route */
sealed class ProfileRoute(val route: String) {
    data object Home : ProfileRoute("home")
    data class Profile(val userId: String) : ProfileRoute("profile/{userId}")
}

ディープリンクは、URLまたはintent-filterを介して特定のアプリケーション画面を開くことを可能にするナビゲーションメカニズムです。Navigation Composeでは、ディープリンクはcomposable()のdeepLinksパラメーターを介して設定され、URIがパターンと一致すると自動的に処理されます。

ディープリンクはUriPatternリストとして指定されます:"https://example.com/profile/{userId}"。URIパラメーターは自動的にルート引数にマッピングされます。NavControllerはアプリケーション起動時(intent経由)と実行中(暗黙的ディープリンク経由)でディープリンクを処理します。保留中のディープリンクを処理するには、グラフ初期化後にNavControllerでhandleDeepLink()を使用します。

Googleによると、ディープリンクは以下に推奨されています:プッシュ通知(Firebase Dynamic Links)、メール確認、コンテンツ共有、Webリンクからのクロスナビゲーション。Android 12+では、ディープリンクの権限を検証するためにDigital Asset Linksが使用されます。AndroidManifest.xmlには、ダイアログなしでリンクを開くためにautoVerify="true"のintent-filterを含める必要があります。

kotlin
composable(
    route = "profile/{userId}",
    arguments = listOf(navArgument("userId") { type = NavType.StringType }),
    deepLinks = listOf(
        navDeepLink { uriPattern = "https://example.com/profile/{userId}" }
    )
) { backStackEntry ->
    ProfileScreen(userId = backStackEntry.arguments?.getString("userId") ?: "")
}

Navigation Composeでのディープリンクの制限:ライブラリは遅延ディープリンクをサポートしていません。ディープリンクはNavHostがグラフを完全に構築した後にのみ処理されます。グラフ初期化前にディープリンクが到着した場合は、intent?.dataを介して遅延させ、LaunchedEffectで処理する必要があります。Firebase Dynamic Linksの場合は、Navigation Composeと一緒にFirebase Dynamic Links SDKを使用してください。

画面間のトランジションアニメーション

Navigation Composeは、composable()のenterTransitionexitTransitionpopEnterTransitionpopExitTransitionパラメーターを介してトランジションアニメーションをサポートしています。アニメーションはCompose Animation API(fadeIn、slideInHorizontally、expandInなど)を使用して実装されます。デフォルトではアニメーションは無効になっており、画面は即座に切り替わります。

一般的なアニメーションシナリオ:前方ナビゲーションにはslideInHorizontally(画面が右からスライドイン)、戻るにはslideOutHorizontally(画面が右にスライドアウト)。BottomNavigationでは、スライドなしのフェードアニメーションがより一般的に使用されます。アニメーションはNavHostを介して設定され、個別に指定されない限りすべてのcomposableに適用されます。

kotlin
NavHost(
    navController = navController,
    startDestination = "home",
    enterTransition = { slideInHorizontally() + fadeIn() },
    exitTransition = { slideOutHorizontally() + fadeOut() },
    popEnterTransition = { fadeIn() },
    popExitTransition = { slideOutHorizontally() + fadeOut() }
) { /* composable */ }

アニメーションパラメーターをcomposable()に直接渡すことで、各composableごとに個別にアニメーションを上書きできます。重要なのは、アニメーションがシステムのバックプレスアニメーションと競合しないことです。共有要素トランジションには、accompanist-navigation-animationライブラリまたはModifier.graphicsLayerを介したカスタム実装が必要です。Android Developers(2025)によると、本番アプリケーションの80%が標準ナビゲーションに水平スライドアニメーションを使用しています。

よくある質問

Navigation ComposeはView用のNavigation Componentとどう違いますか?

Navigation ComposeはFragmentなしで動作し、グラフにcomposable関数とKotlin DSLを使用します。Navigation Component(View)はFragmentManagerとXMLグラフに基づいています。Composeバージョンはよりシンプルで高速で、Fragmentのライフサイクルがありません。View用のNavigation Componentはハイブリッドアプリケーションにのみ適しています。

画面間で複雑なオブジェクトを渡すには?

オブジェクトのIDを渡し、SavedStateHandleを使用してViewModelを介してデータをロードすることをお勧めします。オブジェクトが単純な場合は、kotlinx.parcelizeを介してParcelableを使用してください。引数(Bundle)を介して大きなオブジェクトを直接渡すと、〜1 MBの制限があり、TransactionTooLargeExceptionが発生する可能性があります。

Navigation Composeはネストされたグラフをサポートしていますか?

はい、NavHost内のnavigation(route, startDestination)関数を介してサポートしています。ネストされたグラフは独自のstartDestinationを持ち、共通のルートプレフィックスの下で結合されます。これにより、各機能モジュール用に分離されたグラフを持つモジュラーアーキテクチャを編成できます。

Navigation Composeでシステムの戻るボタンを処理するには?

NavControllerはComposeのBackHandlerを介してバックプレスを自動的に処理します。戻るが押されたらnavController.popBackStack()を呼び出します。カスタム処理(終了確認)の場合は、popBackStack()を呼び出す前にBackHandler(enabled = condition) { callback }を使用します。

Navigation ComposeはJetpack Compose Multiplatformで使用できますか?

現在、Navigation ComposeはCompose Multiplatformでサポートされていません。クロスプラットフォームプロジェクトのiOS部分には、VoyagerまたはDecomposeを使用してください。GoogleはKMPサポートに取り組んでいますが、リリース時期は未定です。Androidのみのプロジェクトでは、Navigation Composeが唯一の推奨オプションです。

まとめ

  • Navigation Compose — Composeでの宣言的ナビゲーションのためのJetpackライブラリ。ルートグラフとNavControllerを介して動作
  • NavControllerはバックスタックを管理し、ナビゲーションのためのnavigate、popBackStackメソッドを提供
  • NavHostはcomposable()を介してコントローラーをグラフに結び付け、モジュラーアーキテクチャのためのネストされたグラフをサポート
  • 引数はNavTypeを介してString、Int、Parcelable、およびKotlin Serializationを使用した型安全ナビゲーションをサポートして渡される
  • ディープリンクはURLやプッシュ通知からの外部ナビゲーションのためにUriPattern付きのnavDeepLinkを介して設定される
  • アニメーションはCompose Animation APIを使用してenterTransition、exitTransitionを介して設定される
  • ライブラリは追加設定なしではKMPとBottomNavigationのマルチバックスタックをサポートしない

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください