I have one variable in screen A as val phoneNumberState = remember { mutableStateOf("") }
and I want to pass this argument to screen B, so I try to do it on internet, there is some example, I confused how to apply, is there easy way for it?
navigation:
@OptIn(ExperimentalPagerApi::class) @Composable fun Navigation( startDestination: String ) {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = startDestination) {
composable("screenA" ) {
ScreenA(navController = navController)
}
composable("screenB") {
ScreenB(navController = navController)
}}}
ScreenA:
@Composable
fun ScreenA(
navController: NavController,
) {
val phoneNumberState = remember { mutableStateOf("") }
OutlinedTextField(
value = phoneNumberState.value,
colors = TextFieldDefaults.textFieldColors(
backgroundColor = white,
focusedIndicatorColor = Grey,
unfocusedIndicatorColor = Grey,
focusedLabelColor = Grey,
unfocusedLabelColor = Grey,
cursorColor = color,
textColor = color,
),
onValueChange = { phoneNumberState.value = it },
label = { Text(text = "Phone Number") },
placeholder = { Text(text = "Phone Number") },
singleLine = true,
)
Button(
modifier = Modifier
.width(285.dp)
.height(55.dp)
,
onClick = {
},
colors = ButtonDefaults.buttonColors(
backgroundColor = color
),
shape = RoundedCornerShape(40),
) {
Text(
text = "send",
style = TextStyle(
fontSize = 18.sp,
color = white,
)
)
}
ScreenB:
@Composable
fun ScreenB(
navController: NavController,
) {
lateinit var resendToken: PhoneAuthProvider.ForceResendingToken
val focusManager = LocalFocusManager.current
val phoneNumberPatientOTP = remember { mutableStateOf("") }
val context = LocalContext.current
LaunchedEffect(Unit) {
println("found activity? ${context.findActivity()}")
val activity = context.findActivity() ?: return@LaunchedEffect
modelAuthentication.setActivity(activity)
}
Column(
Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
OutlinedTextField(
value = phoneNumberOTP.value,
colors = TextFieldDefaults.textFieldColors(
backgroundColor = white,
focusedIndicatorColor = Grey,
unfocusedIndicatorColor = Grey,
focusedLabelColor = Grey,
unfocusedLabelColor = Grey,
cursorColor = color,
textColor = color,
),
onValueChange = { phoneNumberOTP.value = it },
label = { Text(text = "Verify code") },
placeholder = { Text(text = "Verify code") },
modifier = Modifier.fillMaxWidth(0.8f),
)
}
Spacer(modifier = Modifier.padding(7.dp))
Row(
Modifier
.width(300.dp),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
) {
Text(
"Resend Code",
modifier = Modifier
.height(20.dp)
.clickable {
}
,
textAlign = TextAlign.End,
fontWeight = FontWeight.Medium,
fontSize = 14.sp,
color = color
)
} }
CodePudding user response:
According to Navigation compose document:
first change your ScreenB's constructor to this:
@Composable
fun ScreenB(
navController: NavController,
number: String
) {...}
then change your NavHost setup like below:
val navController = rememberNavController()
NavHost(navController = navController, startDestination = startDestination) {
composable("screenA" ) {
ScreenA(navController = navController)
}
composable("screenB/{number}") { backStackEntry ->
ScreenB(navController = navController , backStackEntry.arguments?.getString("number"))
}}}
then in your button onclick in ScreenA call navigate with your state value
onClick = {
navController.navigate("screenB/${phoneNumberState.value}")
}
now you have access to your number in ScreenB's constructor :)
UPDATE
if you want to pass it to another Composable from ScreenB then first you should create your new Screen
@Composable
fun ScreenC(
navController: NavController,
number: String
) {...}
then add the new destination to your NavHost:
val navController = rememberNavController()
NavHost(navController = navController, startDestination = startDestination) {
composable("screenA" ) {
ScreenA(navController = navController)
}
composable("screenB/{number}") { backStackEntry ->
ScreenB(navController = navController , backStackEntry.arguments?.getString("number"))
composable("screenC/{number}") { backStackEntry ->
ScreenC(navController = navController , backStackEntry.arguments?.getString("number"))
}}}
number in your ScreenB is now a variable of type string. its not state anymore, so if you want to use it in ScreenB just call a simple navigate fun and use your number variable:
onClick = {
navController.navigate("screenC/$number")
}
CodePudding user response:
First, you need to add argument placeholders to your route.
composable("screenB/{phoneNumber}")
and you can append your value like this, I assume you want to do it inside Button's onClick lambda
onClick = {
navController.navigate("screenB/${phoneNumberState.value}")
}
then retrieve it like this, inside your NavHost
NavHost(...){
composable("screenB/{phoneNumber}") { backStackEntry ->
ScreenB(navController, backStackEntry.arguments?.getString("phoneNumber"))
}
}