En ocasiones vamos a querer definir una navegación a una ventana pasando un parámetro, para ello debemos seguir los siguientes pasos
1
Definir un Screen con una ruta dinámica
Creamos un Screen cuya route tiene una variable (se declara entre llaves). Además, añadimos un método createRoute que sustituye el valor de un parámetro en la ruta final.
// Dentro de la sealed class definimos un object por cada ruta existenten
sealed class Screen(val route: String) {
data object Home : Screen("home")
data object Login : Screen("login")
// Definimos la ruta Details, esta pantalla tiene una parámetro id
data object Details : Screen("details/{id}") {
fun createRoute(id: String) = "details/$id"
}
}
2
Especifica el valor del parámetro al hacer la navegación
import androidx.compose.runtime.Composable
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
@Composable
fun HomeScreen(navController: NavController) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
) {
Text(
text = "Home Screen",
style = MaterialTheme.typography.headlineMedium
)
Spacer(modifier = Modifier.height(16.dp))
Button(
// Al pulsar en el botón abre la ventana de Detalles con el parámetro 123
onClick = { navController.navigate(Screen.Details.createRoute("123")) }
) {
Text("Go to Details")
}
Spacer(modifier = Modifier.height(16.dp))
Button(
onClick = { navController.navigate(Screen.Login.route) }
) {
Text("Logout")
}
}
}
Registramos la ruta dinámica en navHost y obtenemos el valor del parámetro a partir del backStackEntry
import androidx.compose.runtime.Composable
import androidx.navigation.NavHost
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
// El startDestination define la pantalla que se cargará cuando se abre la aplicación
@Composable
fun NavGraph(startDestination: String = Screen.Home.route) {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = startDestination) {
composable(Screen.Home.route) {
HomeScreen(navController)
}
composable(Screen.Login.route) {
LoginScreen(navController)
}
// Definimos que para la ruta Screen.Details se cargue el composable DetailsScreen(navController, id)
composable(Screen.Details.route) { backStackEntry ->
// Como esta ruta tiene parámetro puedo obtenerlo así, el nombre
// de este parámetro debe coincidir con el declarado en Screen.Details.route
val id = backStackEntry.arguments?.getString("id")
// Crea la screen DetailsScreen con los parámetros
DetailsScreen(navController, id)
}
}
}