I'm trying to figure out which is the cleanest way...
# compose
p
I'm trying to figure out which is the cleanest way to achieve a loading screen with Compose and MVVM with states. I have a UiState on the viewmodel which represents the loading, sucess and error states, and I have a decode method that loads the app, and that method is called on the init block of the viewmodel of that loading screen. I need to move to the next screen when the load method has been completed, but... how can I do that? I mean... I suposse I must writte a method "openNexScreen()" that must be called when the decode method has ended. But which is the correct behaviour? Should i change the uiState to success? and how can I call that method when the success state is enabled?
The loading screen:
Copy code
@Composable
fun LoadingScreen(
    viewModel: LoadingScreenViewModel = viewModel(factory = LoadingScreenViewModel.factory(LocalContext.current)),
    modifier: Modifier = Modifier
) {
    val uiState = viewModel.uiState

    Column(
        modifier = modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(
            text = "Loading Screen"
        )
        Spacer(
            modifier = Modifier.height(32.dp)
        )
        CircularProgressIndicator(
            modifier = Modifier.width(64.dp),
            color = MaterialTheme.colorScheme.secondary,
            trackColor = MaterialTheme.colorScheme.surfaceVariant,
        )
    }
}
The viewmodel:
Copy code
sealed interface UiState {
    object Success : UiState
    object Error : UiState
    object Loading : UiState
}

class LoadingScreenViewModel(
    val context: Context
): ViewModel() {
    private val _uiState = MutableStateFlow(UiState.Loading)
    val uiState: StateFlow<UiState> = _uiState.asStateFlow()

    init {
        decode()
    }

    private fun decode() {
       viewModelScope.launch {
            withContext(Dispatchers.Default) {
                App.decodeApp(context)
            }
            _uiState.value = UiState.Success
        }
    }

    private fun openNextScreen() {
        //open next screen
        //where should I call this method?
    }

    companion object {
        fun factory(myString: Context) : ViewModelProvider.Factory = viewModelFactory {
            initializer {
                LoadingScreenViewModel(
                    myString
                )
            }
        }
    }
}
I'm doing:
Copy code
_uiState.value = UiState.Success
when the decode has ended, but should I simply call the openNextScreen() function after the state change? or should by some way listen to that state change for calling the function automatically? how?