Możesz używać wbudowanych interfejsów API z bezpieczeństwem typów, aby zapewnić bezpieczeństwo typów w czasie kompilacji w przypadku wykresu nawigacji. Te interfejsy API są dostępne, gdy aplikacja korzysta z Navigation
Compose lub Navigation Kotlin DSL. Są one dostępne od wersji Navigation
2.8.0.
Te interfejsy API są odpowiednikiem tego, co Safe Args udostępnia na potrzeby wykresów nawigacji utworzonych za pomocą XML.
Definiowanie tras
Aby używać tras z bezpieczeństwem typów w Compose, musisz najpierw zdefiniować klasy lub obiekty, które można serializować i które reprezentują Twoje trasy.
Aby zdefiniować obiekty, które można serializować, użyj @Serializable adnotacji udostępnianej przez
wtyczkę Kotlin Serialization.
Tę wtyczkę możesz dodać do projektu, dodając te
zależności.
Aby zdecydować, jakiego typu użyć w przypadku trasy, zastosuj te reguły:
- Obiekt: użyj obiektu w przypadku tras bez argumentów.
- Klasa: użyj klasy lub klasy danych w przypadku tras z argumentami.
KClass<T>: użyj, jeśli nie musisz przekazywać argumentów, np. klasy bez parametrów lub klasy, w której wszystkie parametry mają wartości domyślne- Przykład:
Profile::class
- Przykład:
W każdym przypadku obiekt lub klasa musi być serializowalna.
Przykład:
// Define a home route that doesn't take any arguments
@Serializable
object Home
// Define a profile route that takes an ID
@Serializable
data class Profile(val id: String)
Tworzenie wykresu
Następnie musisz zdefiniować wykres nawigacji. Użyj funkcji composable()
, aby zdefiniować elementy kompozycyjne jako miejsca docelowe na wykresie nawigacji.
NavHost(navController, startDestination = Home) {
composable<Home> {
HomeScreen(onNavigateToProfile = { id ->
navController.navigate(Profile(id))
})
}
composable<Profile> { backStackEntry ->
val profile: Profile = backStackEntry.toRoute()
ProfileScreen(profile.id)
}
}
W tym przykładzie zwróć uwagę na te kwestie:
composable()przyjmuje parametr typu. Czylicomposable<Profile>.- Zdefiniowanie typu miejsca docelowego jest bardziej niezawodnym podejściem niż przekazywanie
routeciągu, jak w przypadkucomposable("profile"). - Klasa trasy definiuje typ każdego argumentu nawigacji, np.
val id: String, więc nie jest potrzebnyNavArgument. - W przypadku trasy profilu metoda rozszerzenia
toRoute()odtwarza obiektProfilezNavBackStackEntryi jego argumentów.
Więcej informacji o tym, jak zaprojektować wykres, znajdziesz na stronie Projektowanie wykresu nawigacji.
Dostęp do argumentów w ViewModel
Aby uzyskać dostęp do argumentów z trasy z bezpieczeństwem typów w ViewModel, możesz pobrać
trasę z SavedStateHandle, wywołując
SavedStateHandle.toRoute<T>(), gdzie T jest klasą trasy:
class ProfileViewModel(
savedStateHandle: SavedStateHandle
) : ViewModel() {
private val profile = savedStateHandle.toRoute<Profile>()
private val userInfo: Flow<UserInfo> = userInfoRepository.getUserInfo(profile.id)
}
Przechodzenie do trasy z bezpieczeństwem typów
Na koniec możesz przejść do elementu kompozycyjnego za pomocą navigate()
funkcji, przekazując instancję trasy:
navController.navigate(Profile(id = 123))
Spowoduje to przejście użytkownika do miejsca docelowego composable<Profile> na
wykresie nawigacji. Wszystkie argumenty nawigacji, np. id, można uzyskać, odtwarzając Profile za pomocą NavBackStackEntry.toRoute i odczytując jego właściwości.