0

I'm trying Jetpack Compose on Android with a viewmodel and StateFlow on a super small game application, and I've followed the codelabs, but when I update my state, nothing happens on the UI. I'm sure I'm missing something stupid, but I'm unable to see it. Here's my code inside the view model:

    private val _uiState = MutableStateFlow(HomeScreenState())
    val uiState = _uiState.asStateFlow()

...

    private fun popLists() {
        uiState.value.apply {
            currentLetters = lettersList.pop()
            where = wordPartsList.pop()
        }
    }

in the screen of the app I do

        val gameUiState by viewModel.uiState.collectAsState()

and then in the composition

        BombDisplay(gameUiState.currentLetters, context)

BombDisplay is a simple custom composable with a Text with predetermined style and a background. The "HomeScreenState" is also a simple data class with a couple of Strings in it.

There's also a button that when pressed calls a public method from the viewmodel that calls the "popList" function. I followed the entire thing with the debugger and it all actually works, but the UI seems unaware of the changes to the data.

I've retraced all the steps from varius codelabs and tutorials, but I don't get where the mistake is.

  • `StateFlow` works best with immutable classes. `HomeScreenState` apparently is mutable, and `StateFlow` has no way to know when you go in and change data *within* the existing `value`. I recommend making `HomeScreenState` be a `data class` with `val` properties, then use the `copy()` approach [suggested in the answer](https://stackoverflow.com/a/75117856/115145). – CommonsWare Jan 14 '23 at 12:47

1 Answers1

1

The problem is in the popLists method. Instead of updating the old value u should pass the new value, smth like:

private fun popLists() {
    val newState = uiState.value.copy(
        currentLetters = lettersList.pop(),
        where = wordPartsList.pop()
    )
    uiState.value = newState
}
Sergei Mikhailovskii
  • 2,100
  • 2
  • 21
  • 43
  • Thank that was it! But I must point out that the last line is wrong, I had to change the backup property _uiState, cause uiState is a val. But with that little correction it now works! – Luca Afrune Jan 14 '23 at 13:06
  • seems strange. it should be ok with val uiState. can u please share the full class? – Sergei Mikhailovskii Jan 14 '23 at 13:27