Для обеспечения типобезопасности на этапе компиляции вашего графа навигации можно использовать встроенные типобезопасные 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() для определения объектов 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)
}
Перейдите к вводу безопасного маршрута.
Наконец, вы можете перейти к своему составному объекту, используя функцию navigate() , передав в качестве параметра экземпляр маршрута:
navController.navigate(Profile(id = 123))
Эта команда направляет пользователя к composable<Profile> в графе навигации. Любые аргументы навигации, такие как id , можно получить, восстановив Profile с помощью NavBackStackEntry.toRoute и прочитав его свойства.