Kotlin DSL を使用してグラフを作成する場合、デスティネーションと 1 つのファイルに含まれるナビゲーション イベントを維持するのが難しい場合があります。これは、 複数の独立した特徴がある場合は特にそうです
宛先の抽出
リンク先を NavGraphBuilder
拡張機能に移行する
使用できます。それらを定義するルートの近くに住む必要があり、
表示画面。たとえば、次のアプリレベルのコードについて考えてみましょう。
これは、連絡先のリストを表示するデスティネーションを作成します。
// MyApp.kt
@Serializable
object Contacts
@Composable
fun MyApp() {
...
NavHost(navController, startDestination = Contacts) {
composable<Contacts> { ContactsScreen( /* ... */ ) }
}
}
ナビゲーション固有のコードを別のファイルに移動する必要があります。
// ContactsNavigation.kt
@Serializable
object Contacts
fun NavGraphBuilder.contactsDestination() {
composable<Contacts> { ContactsScreen( /* ... */ ) }
}
// MyApp.kt
@Composable
fun MyApp() {
...
NavHost(navController, startDestination = Contacts) {
contactsDestination()
}
}
ルートとデスティネーションの定義がメインアプリから分離され、
個別に更新できますメインアプリは 1 つの
できます。この例では、
NavGraphBuilder.contactsDestination()
。
NavGraphBuilder
拡張関数は、ステートレス
画面レベルのコンポーズ可能な関数と Navigation 固有のロジックがあります。このレイヤは、
状態の発生元とイベントの処理方法も定義します。
例
次のスニペットでは、新しいデスティネーションを導入して連絡先の 既存の連絡先リストの宛先を更新して 連絡先の詳細を表示する。
独自のモジュールに internal
できる一般的な画面セットを以下に示します。
他のモジュールがそれにアクセスできないようにすることができます。
// ContactScreens.kt
// Displays a list of contacts
@Composable
internal fun ContactsScreen(
uiState: ContactsUiState,
onNavigateToContactDetails: (contactId: String) -> Unit
) { ... }
// Displays the details for an individual contact
@Composable
internal fun ContactDetailsScreen(contact: ContactDetails) { ... }
デスティネーションを作成する
次の NavGraphBuilder
拡張関数は、デスティネーションを作成します。
ContactsScreen
コンポーザブルが表示されます。また、オンプレミス ネットワークと
ViewModel
を使って、画面の UI 状態を提供し、
画面関連のビジネス ロジックです。
連絡先情報のデスティネーションへの移動などのナビゲーション イベントは、
ViewModel
で処理されず、呼び出し元に公開されます。
// ContactsNavigation.kt
@Serializable
object Contacts
// Adds contacts destination to `this` NavGraphBuilder
fun NavGraphBuilder.contactsDestination(
// Navigation events are exposed to the caller to be handled at a higher level
onNavigateToContactDetails: (contactId: String) -> Unit
) {
composable<Contacts> {
// The ViewModel as a screen level state holder produces the screen
// UI state and handles business logic for the ConversationScreen
val viewModel: ContactsViewModel = hiltViewModel()
val uiState = viewModel.uiState.collectAsStateWithLifecycle()
ContactsScreen(
uiState,
onNavigateToContactDetails
)
}
}
同じ方法で、表示するデータを表示するデスティネーションを作成できます。
ContactDetailsScreen
。この例では、UI の状態を Pod から取得する代わりに、
NavBackStackEntry
から直接取得できます。
// ContactsNavigation.kt
@Serializable
internal data class ContactDetails(val id: String)
fun NavGraphBuilder.contactDetailsScreen() {
composable<ContactDetails> { navBackStackEntry ->
ContactDetailsScreen(contact = navBackStackEntry.toRoute())
}
}
ナビゲーション イベントをカプセル化する
デスティネーションをカプセル化するのと同じように、デスティネーションを
使用してルートタイプを不必要に公開しないようにできます。手順
NavController
で拡張関数を作成する。
// ContactsNavigation.kt
fun NavController.navigateToContactDetails(id: String) {
navigate(route = ContactDetails(id = id))
}
まとめ
連絡先を表示するナビゲーション コードが ナビゲーション グラフを使用します。アプリは次のことを行う必要があります。
NavGraphBuilder
拡張関数を呼び出してデスティネーションを作成するNavController
拡張関数を呼び出して、これらのデスティネーションを接続します ナビゲーション イベント
// MyApp.kt
@Composable
fun MyApp() {
...
NavHost(navController, startDestination = Contacts) {
contactsDestination(onNavigateToContactDetails = { contactId ->
navController.navigateToContactDetails(id = contactId)
})
contactDetailsDestination()
}
}
まとめ
- 関連する画面セットのナビゲーション コードをカプセル化します。 別のファイルに
NavGraphBuilder
で拡張関数を作成してデスティネーションを公開するNavController
の拡張関数を作成してナビゲーション イベントを公開するinternal
を使用して画面とルートタイプを非公開にする