Viktor Petrovski
09/05/2021, 8:21 PMColton Idle
09/05/2021, 8:22 PMViktor Petrovski
09/05/2021, 8:23 PMViktor Petrovski
09/05/2021, 8:25 PM@Composable
fun Navigation() {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = Screens.SplashScreen.route) {
composable(Screens.SplashScreen.route) {
val authViewModel = hiltViewModel<AuthViewModel>(it)
SplashScreen(authViewModel, navController)
}
composable(Screens.Home.route) {
val feedViewModel = hiltViewModel<FeedViewModel>()
HomeFeedScreen(feedViewModel.state.value)
}
}
}
@Composable
fun SplashScreen(
viewModel: AuthViewModel,
navController: NavController
) {
val state = viewModel.state.collectAsState()
if (state.value.isSuccess) {
navController.navigate(Screens.Home.route) {
popUpTo(Screens.SplashScreen.route) {
inclusive = true
}
}
} else {
// Render view...
}
ViewModel:
@HiltViewModel
class AuthViewModel
@Inject constructor(private val useCase: CreateAnonymousUserUseCase) :
ViewModel() {
private val _state: MutableStateFlow<AnonAuthResponse> = MutableStateFlow(AnonAuthResponse())
val state: StateFlow<AnonAuthResponse> = _state
init {
crateAnonUser()
}
private fun crateAnonUser() {
viewModelScope.launch {
useCase.createAnonymousUser().collect {
_state.value = _state.value.copy(isSuccess = it.isSuccess, loading = it.loading)
}
}
}
}
Added delay instead of the actual network request to maket things easier:
fun createAnonymousUser(): Flow<AnonAuthResponse> = flow {
kotlinx.coroutines.delay(2500)
emit(AnonAuthResponse(isSuccess = true))
}
If I remove the delay everything works fine, but when I add it it keeps on navigating to HomeScreen and re-rendering the SplashScreen.
Thanks 🙏Ian Lake
09/05/2021, 9:53 PMnavigate()
as part of composition. That's always wrong (composition should never have side effects) - you'll end up calling navigate()
on every frame of the animation between destinations, which is absolutely not what you wantIan Lake
09/05/2021, 9:53 PMIan Lake
09/05/2021, 9:55 PMColton Idle
09/05/2021, 9:59 PMadjpd
09/05/2021, 10:42 PMColton Idle
09/05/2021, 10:58 PMViktor Petrovski
09/06/2021, 7:35 AMIan Lake
09/06/2021, 2:41 PMif (state.value.isSuccess) {
// Use the value as the key
// so that it only happens once
LaunchedEffect(state.value) {
// Call navigate here
}
}
Viktor Petrovski
09/06/2021, 2:42 PMColton Idle
09/06/2021, 5:24 PMLaunchedEffect(state.value.isSuccess)
?Viktor Petrovski
09/06/2021, 5:24 PMIan Lake
09/06/2021, 9:22 PMby
and you wouldn't need the .value
everywhere in the first place, but yes, I was assuming immutable objects where it wouldn't make a difference - the point is that the Launched effect would run just once for a given value change