Вы можете использовать встроенные API с безопасностью типов, чтобы обеспечить безопасность типов во время компиляции для графа навигации. Эти API доступны, если в приложении используется Navigation Compose или Navigation Kotlin DSL. Они доступны с Navigation
2.8.0.
Эти API выполняют те же функции, что и Safe Args для графов навигации, созданных с помощью XML.
Как задать маршруты
Чтобы использовать маршруты с безопасной типизацией в Compose, сначала нужно определить сериализуемые классы или объекты, представляющие маршруты.
Чтобы определить сериализуемые объекты, используйте аннотацию @Serializable, предоставленную плагином Kotlin Serialization.
Чтобы добавить этот плагин в проект, добавьте следующие зависимости.
Чтобы выбрать тип маршрута, следуйте приведенным ниже правилам.
- Объект. Используйте объект для маршрутов без аргументов.
- Класс. Используйте класс или класс данных для маршрутов с аргументами.
KClass<T>– используется, если не нужно передавать аргументы, например для класса без параметров или класса, в котором все параметры имеют значения по умолчанию.- Пример:
Profile::class
- Пример:
В любом случае объект или класс должен быть сериализуемым.
Пример:
// 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)
Как построить график
Затем вам нужно определить граф навигации. Используйте функцию composable(), чтобы определить компонуемые функции как пункты назначения в графе навигации.
NavHost(navController, startDestination = Home) {
composable<Home> {
HomeScreen(onNavigateToProfile = { id ->
navController.navigate(Profile(id))
})
}
composable<Profile> { backStackEntry ->
val profile: Profile = backStackEntry.toRoute()
ProfileScreen(profile.id)
}
}
Обратите внимание на следующее:
composable()принимает параметр типа. То естьcomposable<Profile>.- Определение типа целевой страницы – более надежный подход, чем передача
routeстроки, как вcomposable("profile"). - Класс маршрута определяет тип каждого аргумента навигации, как в
val id: String, поэтому нет необходимости использоватьNavArgument. - Для маршрута профиля метод расширения
toRoute()воссоздает объектProfileиз объектаNavBackStackEntryи его аргументов.
Подробнее о том, как создать граф, рассказывается на странице Как спроектировать граф навигации.
Как получить доступ к аргументам в ViewModel
Чтобы получить аргументы из маршрута с безопасностью типов в ViewModel, можно извлечь маршрут из SavedStateHandle, вызвав SavedStateHandle.toRoute<T>(), где T – класс маршрута:
class ProfileViewModel(
savedStateHandle: SavedStateHandle
) : ViewModel() {
private val profile = savedStateHandle.toRoute<Profile>()
private val userInfo: Flow<UserInfo> = userInfoRepository.getUserInfo(profile.id)
}
Как перейти к безопасному маршруту
Наконец, вы можете перейти к composable-функции, используя функцию navigate(), передав ей экземпляр маршрута:
navController.navigate(Profile(id = 123))
Пользователь переходит к пункту назначения composable<Profile> в графе навигации. Любые аргументы навигации, например id, можно получить, воссоздав Profile с помощью NavBackStackEntry.toRoute и прочитав его свойства.