在 Compose 中使用 StateFlow 更改状态时,对象的属性不会更新

问题描述 投票:0回答:1

我按照上次的谷歌教程在新项目中引入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
android user-interface android-jetpack-compose viewmodel stateflow
1个回答
0
投票

您将相同的对象传递给

currentState.copy(selectedStep = newStep)
- 您可以记录对象地址以查看它 - 从 Compose 的角度来看,这意味着该对象没有更改,因此不需要重新组合。

一个选项是将

status
定义为
mutableStateOf
,在这种情况下,您不需要使用
copy
更新状态:

var status by mutableStateOf(0)

但是,如果您想将代码拆分为视图/数据层以获得更好的可测试性/使其更清晰,则不应将

var
用于要更新的属性,而应在所有级别上使用
copy

appViewModel.updateSelectedStep(selectedStep!!.copy(status = 16))
© www.soinside.com 2019 - 2024. All rights reserved.