Weird SplashScreen "setKeepOnScreenCondition" behavior (with simple minimal example)

22 Views Asked by At

Main activity begins as follows :

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {

        val appViewModel by viewModels<AppViewModel> { AppViewModel.factory }

        installSplashScreen().setKeepOnScreenCondition { appViewModel.isLoading }

        super.onCreate(savedInstanceState)

        setContent {

            val uiState by appViewModel.uiStateFlow.collectAsState()
            val isDynamicTheme by appViewModel.isDynamicTheme.collectAsState()


            AppTheme(dynamicColor = isDynamicTheme) {

                MainScreen(uiState)    

            }

AppViewModel is as follows :


class AppViewModel(val appRepository: AppRepository): ViewModel() {

    var isLoading = true

    val uiStateFlow = ...
    val isDynamicColor = MutableStateFlow(false)

    init {

        viewModelScope.launch{

        // Retrieve data from repository and init values that will be combined into uiStateFlow.
        ...

       // CASE A :
        isDynamicTheme.value = isDynamicTheme.value

       // CASE B :
        isDynamicTheme.value = !isDynamicTheme.value

        isLoading = false

        }

    }

Why in "CASE A" the SplashScreen ends too early and MainScreen briefly shows the default uiState value (as if it didn't finish yet to go through the init in AppViewModel), and not in "CASE B" ?

(In the real app, isDynamicTheme is fetched from a repository, the bug happens when the value from the repository is equal to the default value in val isDynamicColor = MutableStateFlow(false))

Thank you.

EDIT : As a workaround, I wrapped MainScreen(uiState) with if(!appViewModel.isLoading). Of course, not a satisfying solution, an explanation is still needed.

0

There are 0 best solutions below