I am making simple navigation app in jetpack compose. I am changing the screen using compose navigation, using some simple condition but my destination
value is always same what I have initialise. I don't understand why this value is always same as ScreenOne
. If you check the function navigateToScreen
in viewmodel, if condition is true but destination
value is not changing.
FunAppNavigation
@Composable
fun FunAppNavigation(
viewModel: FunAppViewModel = koinViewModel(),
navController: NavHostController = rememberNavController()
) {
val destination = viewModel.navigationHandler.destination.collectAsState()
LaunchedEffect(Unit) {
viewModel.navigateToScreen()
}
LaunchedEffect(key1 = destination) {
navController.navigate(destination.value.route)
}
SideEffect {
println(">> destination Value $destination")
}
}
FunAppViewModel
class FunAppViewModel(
val navigationHandler: NavigationHandler,
) : BaseViewModel() {
fun navigateToScreen() {
val destination = if (true) {
DeviceRoutes.ScreenTwo
} else {
DeviceRoutes.ScreenOne
}
navigationHandler.navigate(destination)
}
}
NavigationHandler
interface NavigationHandler {
val destination: StateFlow<DeviceRoutes>
fun navigate(deviceRoutes: DeviceRoutes)
}
Navigator
class Navigator : NavigationHandler {
private val _destination: MutableStateFlow<DeviceRoutes> =
MutableStateFlow(DeviceRoutes.ScreenOne)
override val destination: StateFlow<DeviceRoutes> = _destination
override fun navigate(deviceRoutes: DeviceRoutes) {
_destination.value = deviceRoutes
}
}
DeviceRoutes
sealed class DeviceRoutes(val route: String) {
object ScreenOne : DeviceRoutes("ScreenOne")
object ScreenTwo : DeviceRoutes("ScreenTwo")
}
I guess you forgot to put .value
inside the key of LaunchedEffect. So it will compare the reference of your state
variable (which is the same) instead of comparing the content of your state which is your destination.
try in this way:
LaunchedEffect(key1 = destination.value) {
navController.navigate(destination.value.route)
}