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.
Navegación
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 único argumento route
para el que
pasar 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
para que cada destino corresponda a un tipo. Para
elementos componibles, lo haces 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 la siguiente fragmento:
- Cada destino del gráfico se crea con una ruta, que es una un objeto o clase serializable que describa los datos requeridos por destino.
- El elemento componible
MyAppNavHost
conserva la instanciaNavController
. - Por lo tanto, las llamadas a
navigate()
deben ocurrir allí y no en un elemento componible inferior comoProfileScreen
. ProfileScreen
contiene un botón que lleva al usuario aFriendsList
cuando hace clic en él. Sin embargo, no llama anavigate()
por su cuenta.- En cambio, el botón llama a una función que se expone como el parámetro
onNavigateToFriends
. - Cuando
MyAppNavHost
agregaProfileScreen
al gráfico de navegación, poronNavigateToFriends
, pasa una lambda que llama anavigate(route = FriendsList
). - De esta manera, se garantiza que, cuando el usuario presione el botón
ProfileScreen
, navegue correctamente aFriendsListScreen
.
@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:
- Cómo crear un controlador de navegación
- Navigation y la pila de actividades
- Navegación con opciones
- Seguridad de tipos en Kotlin DSL y Navigation Compose