使用 Kotlin DSL 建構圖表時,保留目的地並 維護單一檔案中的導覽事件並不容易。這是 特別是當您有多項各自獨立的功能時
擷取目的地
請將目的地移至「NavGraphBuilder
」擴充功能
函式。這些 Pod 必須居住在定義路徑的路徑附近
顯示在畫面上以下列應用程式層級程式碼為例
用於建立顯示聯絡人清單的目的地:
// 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()
}
}
路徑和目的地定義現在與主要應用程式分開
可以單獨更新主要應用程式只會依附於
擴充功能函式。在本例中
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
可組合函式此外,現在
含有提供畫面 UI 狀態的 ViewModel
畫面,並處理
與螢幕相關的商業邏輯
導覽事件 (例如前往聯絡人詳細資料目的地)
,而不是由 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
。在此情況下,請不要從
就能直接從 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
確保螢幕和路線類型不公開