メインコンテンツまでスキップ

Navigation Extension

extension-navigation モジュールは、Compose NavigationNavHostController を Inspector から操作・表示するための Field を提供します。

インストール

starter モジュールには含まれていないため、個別に依存関係を追加する必要があります。

build.gradle.kts
kotlin {
sourceSets {
commonMain.dependencies {
// Compose Preview Lab
implementation("me.tbsten.compose.preview.lab:starter:<version>")

// Navigation Extension
implementation("me.tbsten.compose.preview.lab:extension-navigation:<version>")

// Navigation 本体も必要
implementation("org.jetbrains.androidx.navigation:navigation-compose:<navigation-version>")
}
}
}

利用可能な Field

Field説明
NavControllerFieldNavHostController の状態表示・操作

使用例

NavHostController を Inspector から操作できる Field です。以下の機能を提供します:

  • BackStack 表示: 現在のバックスタック履歴を表示
  • Pop Back: バックスタックから戻る操作
  • Route 選択: PolymorphicField を使用して遷移先を選択
  • パラメータ編集: 引数付き route のパラメータを動的に編集可能
@Serializable
data object Home

@Serializable
data class Profile(val userId: String)

@Serializable
data object Settings

@Preview
@Composable
fun MyScreenPreview() = PreviewLab {
val _navController = rememberNavController()
val navController = fieldValue("navController") {
NavControllerField(
label = "navController",
navController = _navController,
routes = listOf(
// 引数なしの route は FixedField を使用
FixedField("Home", Home),
// 引数付きの route は CombinedField1 等を使用
CombinedField1(
label = "Profile",
field1 = StringField("userId", "default"),
combine = { userId -> Profile(userId = userId) },
split = { profile -> splitedOf(profile.userId) },
),
FixedField("Settings", Settings),
),
)
}

NavHost(
navController = navController,
startDestination = Home,
) {
composable<Home> { HomeScreen() }
composable<Profile> { ProfileScreen() }
composable<Settings> { SettingsScreen() }
}
}

パラメータ

パラメータ説明
labelStringField のラベル
navControllerNavHostController操作対象の NavHostController
routesList<PreviewLabField<out Any>>遷移先の route Field リスト

routes の定義

引数なしの route

FixedField を使用します:

FixedField("Home", Home)
FixedField("Settings", Settings)

引数ありの route

combined() 関数を使用します:

// 1引数の route
combined(
label = "Profile",
field1 = StringField("userId", "default"),
combine = { userId -> Profile(userId = userId) },
split = { profile -> splitedOf(profile.userId) },
)

// 2引数の route
combined(
label = "Article",
field1 = IntField("articleId", 1),
field2 = BooleanField("showComments", true),
combine = { articleId, showComments -> Article(articleId, showComments) },
split = { article -> splitedOf(article.articleId, article.showComments) },
)

型安全なルート定義

Navigation 2.8 以降では、@Serializable アノテーションを使用した型安全なルート定義が推奨されています:

@Serializable
object Home

@Serializable
data class Profile(val userId: String)

@Serializable
data class Article(val articleId: Int, val showComments: Boolean = true)

これらの型を routes パラメータで使用することで、型安全にナビゲーション操作ができます。

関連リンク