Navegar para um destino

O componente Navigation oferece uma maneira direta e genérica de navegar até um destino. Essa interface oferece suporte para diversos contextos e frameworks da interface. Por exemplo, você pode usar o componente Navigation com o Compose, visualizações, fragmentos, atividades e até frameworks personalizados de interface.

Este guia descreve como usar o componente Navigation para navegar até um destino em vários contextos.

Usar um NavController

O tipo principal usado para mudar entre os destinos é o NavController. Consulte Criar um controlador de navegação para mais informações sobre a classe e como criar uma instância dela. Este guia detalha como usá-lo.

Seja qual for o framework da interface usado, há uma única função que pode ser usada para navegar até um destino: NavController.navigate().

Há muitas sobrecargas disponíveis para navigate(). A sobrecarga que você escolhe corresponde ao seu contexto exato. Por exemplo, use uma sobrecarga ao navegar até um elemento combinável e outra ao navegar até uma visualização.

As seções a seguir descrevem algumas das principais sobrecargas de navigate() que você pode usar.

Navegar para um elemento combinável

Para navegar até um elemento combinável, use NavController.navigate<T>. Com essa sobrecarga, navigate() usa um único argumento route para o qual você passar um tipo. Ele serve como a chave para um destino.

@Serializable
object FriendsList

navController.navigate(route = FriendsList)

Para navegar até um elemento combinável no gráfico de navegação, primeiro defina seu NavGraph, para que cada destino corresponda a um tipo. Para elementos combináveis, faça isso com a função composable().

Expor eventos dos elementos combináveis

Quando uma função combinável precisa navegar até uma nova tela, não transmita uma referência a NavController para que ela possa chamar navigate() diretamente. De acordo com os princípios do fluxo de dados unidirecional (UDF, na sigla em inglês), o elemento combinável precisa expor um evento processado por NavController.

Em outras palavras, a função combinável precisa ter um parâmetro do tipo () -> Unit. Ao adicionar destinos a NavHost com a função composable(), transmita ao elemento combinável uma chamada para NavController.navigate().

Confira um exemplo na subseção a seguir.

Exemplo

Como demonstração das seções anteriores, observe esses pontos nos snippet a seguir:

  1. Cada destino no gráfico é criado usando uma rota, que é uma objeto ou classe serializável que descreve os dados exigidos por aquele destino.
  2. O elemento combinável MyAppNavHost contém a instância NavController.
  3. Da mesma forma, as chamadas para navigate() precisam ocorrer lá, e não em um elemento combinável mais baixo, como ProfileScreen.
  4. ProfileScreen contém um botão que direciona o usuário para FriendsList quando clicado. No entanto, ele não chama navigate().
  5. Em vez disso, o botão chama uma função que é exposta como o parâmetro onNavigateToFriends.
  6. Quando MyAppNavHost adiciona ProfileScreen ao gráfico de navegação, por onNavigateToFriends, ela transmite uma lambda que chama navigate(route = FriendsList).
  7. Isso garante que, quando o usuário pressionar o botão ProfileScreen, ele vai navegar corretamente até 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")
    }
}

Navegar usando um ID de número inteiro

Para navegar até um destino usando um ID de número inteiro, chame a sobrecarga navigate(int). Ela usa o ID do recurso de uma ação ou de um destino. O snippet de código a seguir mostra como usar essa sobrecarga para navegar até ViewTransactionsFragment:

Kotlin

viewTransactionsButton.setOnClickListener { view ->
  view.findNavController().navigate(R.id.viewTransactionsAction)
}

Java

viewTransactionsButton.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View view) {
      Navigation.findNavController(view).navigate(R.id.viewTransactionsAction);
  }
});

Ao navegar usando IDs, use ações sempre que possível. As ações oferecem outras informações no gráfico de navegação, mostrando visualmente como seus destinos se conectam uns aos outros.

Navegar usando NavDeepLinkRequest

Para navegar até um destino de link direto implícito, use a sobrecarga navigate(NavDeepLinkRequest). O snippet a seguir oferece uma implementação desse método:

Kotlin

val request = NavDeepLinkRequest.Builder
  .fromUri("android-app://androidx.navigation.app/profile".toUri())
  .build()
findNavController().navigate(request)

Java

NavDeepLinkRequest request = NavDeepLinkRequest.Builder
  .fromUri(Uri.parse("android-app://androidx.navigation.app/profile"))
  .build()
NavHostFragment.findNavController(this).navigate(request)

Ao contrário da navegação usando IDs de ação ou de destino, você pode navegar até qualquer link direto no seu gráfico, não importa se o destino está visível ou não. Você pode navegar até um destino no gráfico atual ou até um destino em um gráfico completamente diferente.

Ações e tipos MIME

Além de Uri, NavDeepLinkRequest também é compatível com links diretos com ações e tipos MIME. Para adicionar uma ação ao pedido, use fromAction() ou setAction(). Para adicionar um tipo MIME a um pedido, use fromMimeType() ou setMimeType().

Para que um NavDeepLinkRequest corresponda corretamente a um destino de link direto implícito, o URI, a ação e o tipo MIME precisam corresponder a NavDeepLink no destino. Os URIs precisam corresponder ao padrão, as ações precisam ser uma correspondência exata e os tipos MIME precisam estar relacionados. Por exemplo, image/jpg corresponde a image/\*.

Outros contextos

Este documento mostra como usar NavController.navigate() nos casos de uso mais comuns. No entanto, a função tem uma variedade de sobrecargas que podem ser usadas em diferentes contextos e em conjunto com qualquer framework de interface. Consulte a documentação de referência para conferir mais detalhes sobre essas sobrecargas.

Leia mais

Para mais informações, consulte as páginas abaixo: