Khi sử dụng Kotlin DSL để tạo biểu đồ, hãy giữ lại các đích đến và sự kiện điều hướng trong một tệp có thể khó duy trì. Đây là đặc biệt đúng nếu bạn có nhiều tính năng độc lập.
Trích xuất đích đến
Bạn nên di chuyển các đích đến vào tiện ích NavGraphBuilder
. Các dịch vụ này phải nằm gần các tuyến đường xác định chúng và
mà chúng hiển thị. Ví dụ: hãy xem xét mã cấp ứng dụng sau đây
để tạo một đích đến cho thấy danh sách người liên hệ:
// MyApp.kt
@Serializable
object Contacts
@Composable
fun MyApp() {
...
NavHost(navController, startDestination = Contacts) {
composable<Contacts> { ContactsScreen( /* ... */ ) }
}
}
Bạn nên di chuyển mã điều hướng cụ thể vào một tệp riêng:
// ContactsNavigation.kt
@Serializable
object Contacts
fun NavGraphBuilder.contactsDestination() {
composable<Contacts> { ContactsScreen( /* ... */ ) }
}
// MyApp.kt
@Composable
fun MyApp() {
...
NavHost(navController, startDestination = Contacts) {
contactsDestination()
}
}
Các tuyến và định nghĩa đích đến hiện đã tách biệt với ứng dụng chính và
bạn có thể tự cập nhật chúng. Ứng dụng chính chỉ phụ thuộc vào một
hàm mở rộng. Trong trường hợp này,
NavGraphBuilder.contactsDestination()
.
Hàm mở rộng NavGraphBuilder
tạo thành cầu nối giữa một hàm không có trạng thái
hàm có khả năng kết hợp cấp màn hình và logic Điều hướng dành riêng. Lớp này có thể
bạn cũng cần xác định nguồn gốc của trạng thái và cách bạn xử lý các sự kiện.
Ví dụ
Đoạn mã sau đây giới thiệu một đích đến mới để hiển thị chi tiết và cập nhật đích đến của danh sách liên hệ hiện có để hiển thị sự kiện điều hướng để hiển thị thông tin chi tiết về người liên hệ đó.
Dưới đây là một nhóm màn hình điển hình có thể internal
đối với mô-đun của riêng chúng, vì vậy
mà các mô-đun khác không thể truy cập vào:
// 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) { ... }
Tạo đích đến
Hàm tiện ích NavGraphBuilder
sau đây tạo một đích đến
cho thấy thành phần kết hợp ContactsScreen
. Ngoài ra, bây giờ
màn hình có ViewModel
cung cấp trạng thái giao diện người dùng màn hình và xử lý
logic nghiệp vụ liên quan đến màn hình.
Các sự kiện điều hướng, chẳng hạn như di chuyển đến đích đến thông tin liên hệ,
được hiển thị với phương thức gọi thay vì được ViewModel
xử lý.
// 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
)
}
}
Bạn có thể sử dụng cùng một phương pháp để tạo đích đến hiển thị
ContactDetailsScreen
. Trong trường hợp này, thay vì lấy trạng thái giao diện người dùng từ
view model, bạn có thể lấy trực tiếp từ NavBackStackEntry
.
// ContactsNavigation.kt
@Serializable
internal data class ContactDetails(val id: String)
fun NavGraphBuilder.contactDetailsScreen() {
composable<ContactDetails> { navBackStackEntry ->
ContactDetailsScreen(contact = navBackStackEntry.toRoute())
}
}
Đóng gói sự kiện điều hướng
Tương tự như cách đóng gói đích đến, bạn có thể đóng gói
các sự kiện điều hướng để tránh hiển thị loại tuyến đường một cách không cần thiết. Thực hiện việc này bằng cách
tạo các hàm mở rộng trên NavController
.
// ContactsNavigation.kt
fun NavController.navigateToContactDetails(id: String) {
navigate(route = ContactDetails(id = id))
}
Kết hợp
Mã điều hướng để hiển thị danh bạ hiện đã được tách biệt rõ ràng khỏi biểu đồ điều hướng của ứng dụng. Ứng dụng cần:
- Gọi các hàm mở rộng
NavGraphBuilder
để tạo đích đến - Kết nối các đích đến đó bằng cách gọi hàm mở rộng
NavController
cho sự kiện điều hướng
// MyApp.kt
@Composable
fun MyApp() {
...
NavHost(navController, startDestination = Contacts) {
contactsDestination( contactId ->
navController.navigateToContactDetails(id = contactId)
})
contactDetailsDestination()
}
}
Tóm tắt
- Đóng gói mã điều hướng của bạn cho một nhóm màn hình liên quan bằng cách đặt mã đó trong một tệp riêng biệt
- Hiển thị đích đến bằng cách tạo các hàm mở rộng trên
NavGraphBuilder
- Hiển thị các sự kiện điều hướng bằng cách tạo hàm tiện ích trên
NavController
- Sử dụng
internal
để bảo mật màn hình và loại tuyến