Перейдите к пункту назначения, Перейдите к пункту назначения

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

Пример этого см. в следующем подразделе.

Пример

В качестве демонстрации предыдущих разделов обратите внимание на эти моменты в следующем фрагменте:

  1. Каждый пункт назначения в графе создается с использованием маршрута, который представляет собой сериализуемый объект или класс, описывающий данные, необходимые для этого пункта назначения.
  2. Составной элемент MyAppNavHost содержит экземпляр NavController .
  3. Соответственно, вызовы navigate() должны происходить там, а не в более низком компоновочном объекте, таком как ProfileScreen .
  4. ProfileScreen содержит кнопку, которая при нажатии перемещает пользователя к FriendsList . Однако он не вызывает саму navigate() .
  5. Вместо этого кнопка вызывает функцию, которая предоставляется как параметр onNavigateToFriends .
  6. Когда MyAppNavHost добавляет ProfileScreen в граф навигации, для onNavigateToFriends он передает лямбда-выражение, которое вызывает navigate(route = FriendsList ).
  7. Это гарантирует, что когда пользователь нажимает кнопку 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() в наиболее распространенных случаях. Однако у функции есть ряд перегрузок, которые можно использовать в разных контекстах и ​​в сочетании с любой платформой пользовательского интерфейса. Более подробную информацию об этих перегрузках см. в справочной документации.

Дальнейшее чтение

Для получения дополнительной информации см. следующие страницы:

,

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

Пример этого см. в следующем подразделе.

Пример

В качестве демонстрации предыдущих разделов обратите внимание на эти моменты в следующем фрагменте:

  1. Каждый пункт назначения в графе создается с использованием маршрута, который представляет собой сериализуемый объект или класс, описывающий данные, необходимые для этого пункта назначения.
  2. Составной элемент MyAppNavHost содержит экземпляр NavController .
  3. Соответственно, вызовы navigate() должны происходить там, а не в более низком компоновочном объекте, таком как ProfileScreen .
  4. ProfileScreen содержит кнопку, которая при нажатии перемещает пользователя к FriendsList . Однако он не вызывает саму navigate() .
  5. Вместо этого кнопка вызывает функцию, которая предоставляется как параметр onNavigateToFriends .
  6. Когда MyAppNavHost добавляет ProfileScreen в граф навигации, для onNavigateToFriends он передает лямбда-выражение, которое вызывает navigate(route = FriendsList ).
  7. Это гарантирует, что когда пользователь нажимает кнопку 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() в наиболее распространенных случаях. Однако у функции есть ряд перегрузок, которые можно использовать в разных контекстах и ​​в сочетании с любой платформой пользовательского интерфейса. Более подробную информацию об этих перегрузках см. в справочной документации.

Дальнейшее чтение

Для получения дополнительной информации см. следующие страницы: