I'm working with Compose and the ViewModel and a list. I don't understand why my UI isn't recomposing when I click on the button, although I am generating a new list.
data class Dice(var value: Int = 6) {
fun roll() {
value = Random.nextInt(6) + 1
}
}
class MainViewModel : ViewModel() {
var diceVal = MutableStateFlow(listOf(Dice()))
fun rollDice() {
//Both not working
//diceVal.value = diceVal.value.map { it.roll(); it.copy() }
diceVal.update { it.map { it.roll(); it.copy() }}
}
}
@Composable
fun MainScreen(modifier: Modifier = Modifier, viewModel: MainViewModel = viewModel { MainViewModel() }) {
Column(modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally) {
var diceList = viewModel.diceVal.collectAsStateWithLifecycle()
diceList.value.forEach {
Button(onClick = {
viewModel.rollDice()
}) {
Text(text = it.value.toString())
}
}
}
}
diceVal.value = listOf(diceVal.value.map { it.roll(); it.copy() })basically you need to give it a new list instead of using the one thats in therelistOf()and isn't modifyable. By callingmapon it, a new list is created - that's not the problem here. Instead the Dice value being declared asvaris the culprit, see my answer for an explanation why that matters and how to solve it.