Android collec flow in viewmodel
Всем доброго времени суток! Стоит задача отображать страницу авторизации, если пользователь не авторизирован, т.е., выполнить условную навигацию.
Данные хранятся в datastore в viewmodel, в методе init происходит сбор (collect), и выполняется условный переход (после коллекта не выполняется), который заставляет SplashScreen исчезать:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val splashScreen = installSplashScreen()
setContent {
AppTheme() {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
val model: UserViewModel = viewModel(
factory = UserViewModel.provideFactory(LocalContext.current)
)
val hasLoggedIn by model.hasLoggedIn.collectAsState()
val status by model.status.collectAsState()
splashScreen.setKeepOnScreenCondition { !status }
if (hasLoggedIn) {
MyAppNavHost()
} else {
LoginScreen()
}
}
}
}
}
class UserViewModel(context: Context) : ViewModel() {
companion object {
fun provideFactory(context: Context): ViewModelProvider.Factory =
object : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return UserViewModel(context) as T
}
}
}
private val dataStore = AppDataStore(context)
private val _hasLoggedIn: MutableStateFlow<Boolean> = MutableStateFlow(false)
val hasLoggedIn = _hasLoggedIn.asStateFlow()
private val _status: MutableStateFlow<Boolean> = MutableStateFlow(false)
val status = _status.asStateFlow()
init {
viewModelScope.launch(Dispatchers.IO) {
dataStore.userExists.collect {
_hasLoggedIn.value = it
}
// не выполняется
_status.value = true
}
}
}
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
class AppDataStore(context: Context) {
companion object {
val USER_EXISTS = booleanPreferencesKey("user_exists")
}
val userExists: Flow<Boolean> = context.dataStore.data
.map {
it[USER_EXISTS] ?: false
}
}