0
votes

I just started learning jetpack compose. I have a very basic question. My ViewModel has a SingleLiveEvent that I use to navigate to another screen.

private val _navigateToDetails: SingleLiveEvent<Movie> = SingleLiveEvent()
val navigateToDetails: MutableLiveData<Movie> = _navigateToDetails

I know that I can use Livedata as state to emit UI but how to use it to trigger some action within composable.

Previously I had used viewLifecycleOwner to observer the state as anyone would do like this.

viewModel.navigateToDetails.observe(viewLifecycleOwner) {
    // navigate to details
}

How do I achieve the same thing in compose. I don't know if that's possible or not. Maybe I am not thinking this in compose way. Any help would be appreciated.

2

2 Answers

1
votes

Actually, in compose we use mutableStateOf() over LiveData. In your viewmodel, you can change the type of the data holder from LiveData to mutableStateOf(...) which will allow you to directly use it in your Composables without explicitly calling observe()

Let's say you wish to store an integer of any kind in your viewmodel and update the state of your Composable based on that.

In your viewmodel,

var mInteger by mutableStateOf (0) //'by' helps treat state as data

fun updateMInteger(newValue: Int){
mInteger = newValue
}

In your Composable, directly call viewmodel.mInteger and Compose being built like that, automatically updates the UI, given that mInteger is being read from the Composable

Like

Text(viewModel.mInteger)
0
votes

I would do something like to make sure I'm only doing it once:

@Composable
fun LoginScreen(viewModel: LoginViewModel) {
    val loginState by viewModel.loginState.observeAsState(null)
    val hasHandledNavigation = remember { mutableStateOf(false)}
    if (loginState != null && !hasHandledNavigation.value ) {
        navigateToWelcomeScreen()
    else {
        // rest of the Compose UI
    }
}