我按照上次的谷歌教程在新项目中引入Compose/ViewModel/State,但是遇到了一个问题,我不明白。当我使用 Viewmodel 中的方法将对象从 null 更新为新实例时,UI 会更新,但是当我使用相同的方法仅更新该对象的一个参数时,修改是不可见的。
这里是代码 视图模型
data class AppOscarUiState(
val selectedStep: Step? = null
)
class AppViewModel() : ViewModel(){
private val _uiState = MutableStateFlow(AppUiState())
val uiState: StateFlow<AppUiState> = _uiState.asStateFlow()
fun updateSelectedStep(newStep: step){
_uiState.update { currentState ->
currentState.copy(selectedStep = newStep)
}
// also tried _uiState.value = _uiState.value.copy(selectedStep = newStep)
}
}
在 Composable 中
fun CardDetail(
appViewModel: AppViewModel
) {
val appUiState by appViewModel.uiState.collectAsState()
Column(
Modifier
.fillMaxSize()
.padding(horizontal = 16.dp, vertical = 8.dp),
) {
Text(
text = appUiState.selectedStep!!.status,
)
OutlinedButton(
onClick = {
selectedStep!!.status = 16
appViewModel.updateSelectedStep(selectedStep)
},
) {
Text(
stringResource(R.string.it_starts),
)
}
}
When the step is selected from a list, ```updateSelectedStep(newStep)``` from the viewmodel is called and a detail container is filled. And when I want to change a parameter, the same is done. A log in ```updateSelectedStep(newStep)``` indicates that the new value is well transmetted, and when the step is deselected and selected again, the new data is visible.
Step is a data class.
So why the modification is not instantaneous ? I have a similar method to update a boolean (not an object) which works fine.
Thanks for your help
您将相同的对象传递给
currentState.copy(selectedStep = newStep)
- 您可以记录对象地址以查看它 - 从 Compose 的角度来看,这意味着该对象没有更改,因此不需要重新组合。
一个选项是将
status
定义为mutableStateOf
,在这种情况下,您不需要使用copy
更新状态:
var status by mutableStateOf(0)
但是,如果您想将代码拆分为视图/数据层以获得更好的可测试性/使其更清晰,则不应将
var
用于要更新的属性,而应在所有级别上使用 copy
:
appViewModel.updateSelectedStep(selectedStep!!.copy(status = 16))