Компонент «Навигация» обеспечивает простой и универсальный способ навигации к месту назначения. Этот интерфейс поддерживает ряд контекстов и инфраструктур пользовательского интерфейса. Например, вы можете использовать компонент «Навигация» с 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
Компонент «Навигация» обеспечивает простой и универсальный способ навигации к месту назначения. Этот интерфейс поддерживает ряд контекстов и инфраструктур пользовательского интерфейса. Например, вы можете использовать компонент «Навигация» с 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