Cómo navegar a un destino

El componente Navigation proporciona una forma sencilla y genérica de navegar a un destino. Esta interfaz admite una variedad de contextos y frameworks de IU. Por ejemplo, puedes usar el componente Navigation con Compose, vistas, fragmentos, actividades y hasta frameworks de IU personalizados.

En esta guía, se describe cómo puedes usar el componente Navigation para navegar a un destino en varios contextos.

Cómo usar NavController

El tipo de clave que usas para moverte entre destinos es NavController. Consulta Cómo crear un controlador de navegación para obtener más información sobre la clase en sí y cómo crear una instancia de esta. En esta guía, se detalla cómo usarlo.

Más allá del framework de IU que uses, hay una sola función que puedes usar para navegar a un destino: NavController.navigate().

Hay muchas sobrecargas disponibles para navigate(). La sobrecarga que debes elegir corresponde a tu contexto exacto. Por ejemplo, debes usar una sobrecarga cuando navegas a un elemento componible y otra cuando navegas a una vista.

En las siguientes secciones, se describen algunas de las sobrecargas clave de navigate() que puedes usar.

Cómo navegar a un elemento componible

Para navegar a un elemento componible, debes usar NavController.navigate<T>. Con esta sobrecarga, navigate() toma un solo argumento route por el que pasas un tipo. Funciona como la clave de un destino.

@Serializable
object FriendsList

navController.navigate(route = FriendsList)

Para navegar a un elemento componible en el gráfico de navegación, primero define tu NavGraph de modo que cada destino corresponda a un tipo. En el caso de los elementos componibles, puedes hacerlo con la función composable().

Cómo exponer eventos de tus elementos componibles

Cuando una función de componibilidad necesita navegar a una pantalla nueva, no debes pasarle una referencia a NavController para que pueda llamar directamente a navigate(). Según los principios del flujo de datos unidireccional (UDF), el elemento componible debería exponer un evento que controle NavController.

En términos más directos, el elemento componible debe tener un parámetro de tipo () -> Unit. Cuando agregues destinos a tu NavHost con la función composable(), pasa al elemento componible una llamada a NavController.navigate().

Consulta la siguiente subsección para ver un ejemplo.

Ejemplo

Como demostración de las secciones anteriores, observa estos puntos en el siguiente fragmento:

  1. Cada destino del gráfico se crea mediante una ruta, que es un objeto o una clase serializables que describen los datos que requiere ese destino.
  2. El elemento componible MyAppNavHost conserva la instancia NavController.
  3. Por lo tanto, las llamadas a navigate() deben ocurrir allí y no en un elemento componible inferior como ProfileScreen.
  4. ProfileScreen contiene un botón que lleva al usuario a FriendsList cuando hace clic en él. Sin embargo, no llama a navigate() por su cuenta.
  5. En cambio, el botón llama a una función que se expone como el parámetro onNavigateToFriends.
  6. Cuando MyAppNavHost agrega ProfileScreen al gráfico de navegación, para onNavigateToFriends, pasa una expresión lambda que llama a navigate(route = FriendsList.
  7. De esta manera, se garantiza que, cuando el usuario presione el botón ProfileScreen, navegue correctamente a 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")
    }
}

Cómo navegar con un ID de número entero

Para navegar a un destino con un ID de número entero, llama a la sobrecarga navigate(int). Esta toma el ID de recurso de una acción o un destino. En el siguiente fragmento de código, se muestra cómo puedes usar esta sobrecarga para navegar a 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);
  }
});

Cuando navegues con IDs, debes usar acciones siempre que sea posible. Las acciones brindan información adicional en tu gráfico de navegación y muestran de manera visual cómo se conectan entre sí tus destinos.

Cómo navegar con NavDeepLinkRequest

Para navegar a un destino de vínculo directo implícito, usa la sobrecarga de navigate(NavDeepLinkRequest). En el siguiente fragmento, se proporciona una implementación de este 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)

A diferencia de la navegación con IDs de acción o destino, puedes navegar a cualquier vínculo directo en tu gráfico, ya sea que el destino esté visible o no. Puedes navegar a un destino en el gráfico actual o a uno en un gráfico completamente diferente.

Acciones y tipos de MIME

Además de Uri, NavDeepLinkRequest también admite vínculos directos con acciones y tipos de MIME. Para agregar una acción a la solicitud, usa fromAction() o setAction(). Para agregar un tipo de MIME a una solicitud, usa fromMimeType() o setMimeType().

Para que una NavDeepLinkRequest coincida de forma adecuada con un destino de vínculo directo implícito, el URI, la acción y el tipo de MIME deben coincidir con el NavDeepLink en el destino. Los URIs deben coincidir con el patrón, las acciones deben ser una coincidencia exacta y los tipos de MIME deben estar relacionados. Por ejemplo, image/jpg coincide con image/\*.

Contextos adicionales

En este documento, se explica cómo usar NavController.navigate() en los casos de uso más comunes. Sin embargo, la función tiene un rango de sobrecargas que puedes usar en diferentes contextos y en conjunto con cualquier framework de IU. Consulta la documentación de referencia para obtener más detalles sobre estas sobrecargas.

Lecturas adicionales

Para obtener más información, consulta las siguientes páginas: