Search code examples
androidandroid-jetpack-composestateandroid-viewmodel

Observing a variable's state within a ViewModel


I'm trying to wrap my head around ViewModels and how variables within are observed. I would like to figure out how to observe variables within a ViewModel and trigger actions when they do change. Please consider the following example code:

My Composable:


@Composable
fun ScreenSetup(viewModel: myViewModel) {


    var whosTurn: Int? by remember { mutableStateOf(viewModel.whosTurn.value) }


    Column {
        Row {
            Text(text = "Current Turn = ${whosTurn}")
        }
        Row {
            Button(onClick = {
                viewModel.newTurn()

            }) {
                Text(text = "Next Turn")
            }
        }
    }


}

My Viewmodel:


class myViewModel : ViewModel() {


   var whosTurn : MutableState<Int> = mutableIntStateOf(1)


    fun newTurn() {

        Log.i("tag",whosTurn.value.toString())

        whosTurn.value += 1

        if (whosTurn.value == 4) {
            whosTurn.value=1
            //sets limit of 3 player game
        }

    }



}


When I execute the simple program, if I click the button the output on the emulator shows "Current Turn = 1" constantly. However if I look at my Log, the variable "whosTurn" is incrementing within the ViewModel as I would like. How do I have the variable "whosTurn" observed correctly so that Current Turn increments?

Thank you so much in advance for considering my question.


Solution

  • In the viewModel you should define your variable like this:

     val _whosTurn = MutableStateFlow(1)
     val whowTurn = _whosTurn.asStateFlow()
    

    In the screen, you can now collect it as state:

    val whosTurn by viewModel.whowTurn.collectAsState()