Компонент «Навигация» обеспечивает простой и универсальный способ навигации к месту назначения. Этот интерфейс поддерживает ряд контекстов и инфраструктур пользовательского интерфейса. Например, вы можете использовать компонент «Навигация» с Compose, представлениями, фрагментами, действиями и даже пользовательскими платформами пользовательского интерфейса.
В этом руководстве описывается, как использовать компонент «Навигация» для навигации к месту назначения в различных контекстах.
Используйте NavController
Тип ключа, который вы используете для перемещения между пунктами назначения, — это NavController
. Дополнительные сведения о самом классе и о том, как создать его экземпляр, см. в разделе Создание контроллера навигации . В этом руководстве подробно описано, как его использовать.
Навигация
Независимо от того, какую структуру пользовательского интерфейса вы используете, для перехода к месту назначения можно использовать одну функцию: NavController.navigate()
.
Для navigate()
доступно множество перегрузок. Перегрузка, которую вам следует выбрать, соответствует вашему конкретному контексту. Например, вам следует использовать одну перегрузку при переходе к составному объекту, а другую — при переходе к представлению.
В следующих разделах описаны некоторые ключевые перегрузки navigate()
которые вы можете использовать.
Перейдите к составному элементу
Чтобы перейти к составному элементу, вы должны использовать NavController.navigate<T>
. При такой перегрузке navigate()
принимает один аргумент route
, для которого вы передаете тип. Он служит ключом к месту назначения.
@Serializable
object FriendsList
navController.navigate(route = FriendsList)
Чтобы перейти к составному объекту в графе навигации, сначала определите свой NavGraph
так, чтобы каждый пункт назначения соответствовал типу . Для составных объектов это можно сделать с помощью функции composable()
.
Предоставляйте события из ваших компонуемых объектов
Когда компонуемой функции необходимо перейти на новый экран, не следует передавать ей ссылку на NavController
, чтобы она могла напрямую вызвать navigate()
. В соответствии с принципами однонаправленного потока данных (UDF) , компонуемый объект должен вместо этого предоставлять событие, которое обрабатывает NavController
.
Проще говоря, ваш составной объект должен иметь параметр типа () -> Unit
. Когда вы добавляете пункты назначения в свой NavHost
с помощью функции composable()
, передайте составной вызов NavController.navigate()
.
Пример этого см. в следующем подразделе.
Пример
В качестве демонстрации предыдущих разделов обратите внимание на эти моменты в следующем фрагменте:
- Каждый пункт назначения в графе создается с использованием маршрута, который представляет собой сериализуемый объект или класс, описывающий данные, необходимые для этого пункта назначения.
- Составной элемент
MyAppNavHost
содержит экземплярNavController
. - Соответственно, вызовы
navigate()
должны происходить там, а не в более низком компоновочном объекте, таком какProfileScreen
. -
ProfileScreen
содержит кнопку, которая при нажатии перемещает пользователя кFriendsList
. Однако он не вызывает самуnavigate()
. - Вместо этого кнопка вызывает функцию, которая предоставляется как параметр
onNavigateToFriends
. - Когда
MyAppNavHost
добавляетProfileScreen
в граф навигации, дляonNavigateToFriends
он передает лямбда-выражение, которое вызываетnavigate(route = FriendsList
). - Это гарантирует, что когда пользователь нажимает кнопку
ProfileScreen
, он правильно переходит кFriendsListScreen
.
@Serializable
object Profile
@Serializable
object FriendsList
@Composable
fun MyAppNavHost(
modifier: Modifier = Modifier,
navController: NavHostController = rememberNavController(),
) {
NavHost(
modifier = modifier,
navController = navController,
startDestination = Profile
) {
composable<Profile> {
ProfileScreen(
onNavigateToFriends = { navController.navigate(route = FriendsList) },
/*...*/
)
}
composable<FriendsList> { FriendsListScreen(/*...*/) }
}
}
@Composable
fun ProfileScreen(
onNavigateToFriends: () -> Unit,
/*...*/
) {
/*...*/
Button(onClick = onNavigateToFriends) {
Text(text = "See friends list")
}
}
Навигация с использованием целочисленного идентификатора
Чтобы перейти к месту назначения с помощью целочисленного идентификатора, вызовите перегрузку navigate(int)
. Он принимает идентификатор ресурса либо действия, либо пункта назначения. В следующем фрагменте кода показано, как можно использовать эту перегрузку для перехода к ViewTransactionsFragment
:
Котлин
viewTransactionsButton.setOnClickListener { view ->
view.findNavController().navigate(R.id.viewTransactionsAction)
}
Ява
viewTransactionsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Navigation.findNavController(view).navigate(R.id.viewTransactionsAction);
}
});
При навигации с помощью идентификаторов следует использовать действия там, где это возможно. Действия предоставляют дополнительную информацию на графике навигации, визуально показывая, как ваши пункты назначения соединяются друг с другом.
Навигация с помощью NavDeepLinkRequest
Чтобы перейти к неявному назначению глубокой ссылки , используйте перегрузку navigate(NavDeepLinkRequest)
. В следующем фрагменте представлена реализация этого метода:
Котлин
val request = NavDeepLinkRequest.Builder
.fromUri("android-app://androidx.navigation.app/profile".toUri())
.build()
findNavController().navigate(request)
Ява
NavDeepLinkRequest request = NavDeepLinkRequest.Builder
.fromUri(Uri.parse("android-app://androidx.navigation.app/profile"))
.build()
NavHostFragment.findNavController(this).navigate(request)
В отличие от навигации с использованием идентификаторов действий или пунктов назначения, вы можете перейти к любой глубокой ссылке на графике, независимо от того, отображается ли пункт назначения. Вы можете перейти к пункту назначения на текущем графике или к пункту назначения на совершенно другом графике.
Действия и типы MIME
Помимо Uri
, NavDeepLinkRequest
также поддерживает глубокие ссылки с действиями и типами MIME. Чтобы добавить действие к запросу, используйте fromAction()
или setAction()
. Чтобы добавить тип MIME в запрос, используйте fromMimeType()
или setMimeType()
.
Чтобы NavDeepLinkRequest
правильно соответствовал неявному назначению глубокой ссылки, URI, действие и тип MIME должны соответствовать NavDeepLink
в месте назначения. URI должны соответствовать шаблону, действия должны точно совпадать, а типы MIME должны быть связаны. Например, image/jpg
соответствует image/\*
Дальнейшие контексты
В этом документе описано, как использовать NavController.navigate()
в наиболее распространенных случаях. Однако у функции есть ряд перегрузок, которые можно использовать в разных контекстах и в сочетании с любой платформой пользовательского интерфейса. Более подробную информацию об этих перегрузках см. в справочной документации.
Дальнейшее чтение
Для получения дополнительной информации см. следующие страницы:
- Создайте навигационный контроллер
- Навигация и задний стек
- Навигация с опциями
- Типовая безопасность в Kotlin DSL и Navigation Compose