I'm trying to figure out what the best practice is in ViewModel. StateFlow, LiveData or ComposeState. Now I have come across something that I can't explain.
Activity:
val viewModel by viewModels<MainViewModel>()
setContent {
val randomAdmin by viewModel.randomAdmin.collectAsStateWithLifecycle()
Spacer(modifier = Modifier.height(20.dp))
Text(text = "Random Admin: ${randomAdmin.name} / ${randomAdmin.age}")
BasicButton("ChangeAnyAdmib"){
viewModel.changeRandomAdmin()
}
}
ViewModel:
class MainViewModel : ViewModel() {
private val _randomAdmin = MutableStateFlow( Admin("Peter",0) )
val randomAdmin = _randomAdmin.asStateFlow()
fun changeRandomAdmin() {
_randomAdmin.value = _randomAdmin.value.copy(name = "Hans")
}
}
Works well. The new admin will be emited. But when I change the ViewModel function code (see below), the new admin will not be emitted. Why? I have the same issue with LiveData & MutableState. It will not emited. Strangely enough, the reference is the same.
fun changeRandomAdmin() {
_randomAdmin.value.name = "Hans"
val oldValue = _randomAdmin.value
_randomAdmin.value = _randomAdmin.value.copy()
Log.d("ViewModelTest" , "Same Object: " + (oldValue === _randomAdmin.value).toString()) // true
}
But when I use this code (see below) the reference is not the same, but it should. Unfortunately the object is still not emitted
fun changeRandomAdmin() {
_randomAdmin.value.name = "Hans"
val oldValue = _randomAdmin.value.copy()
_randomAdmin.value = oldValue
Log.d("ViewModelTest" , "Same Object: " + (oldValue === _randomAdmin.value).toString()) // false
}
I no longer understand the world ;(
It should emit the new object, I thought.