首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从StateFlow收集状态

从StateFlow收集状态
EN

Stack Overflow用户
提问于 2021-05-15 12:12:01
回答 2查看 2.7K关注 0票数 2

我开发了应用程序的组成和MVVM的架构。我有viewModel和每个屏幕的视图状态。ViewModel:

代码语言:javascript
复制
class ProfileViewModel : ViewModel() {

    private val _state = MutableStateFlow(ProfileViewState())
    val state: StateFlow<ProfileViewState> get() = _state

    val actions = Channel<ProfileAction>()

    init {
        viewModelScope.launch {
            combine(_state) {
                ProfileViewState()
            }.collect {
                _state.value = it
            }
    }
}

状态:

代码语言:javascript
复制
class ProfileViewState {
    val nick: MutableStateFlow<String> = MutableStateFlow("default nick")
}

当用户按下按钮时,我会在状态下更改"nick“的值。

代码语言:javascript
复制
_state.value.nick.value = "new nick"

我希望在我的视图中观察状态,并在数据更改时自动更新它们。

代码语言:javascript
复制
@Composable
fun ProfileScreen() {
        val viewModel: ProfileViewModel = viewModel()
        val viewState by viewModel.state.collectAsState()
}

在TextView中,我尝试显示"nick“值

代码语言:javascript
复制
Text(text = viewState.nick.value, style = MaterialTheme.typography.h4)

问题是,当我在状态中更改数据时,屏幕不会做出任何反应,也不会更新。当我打开ProfileScreen时,我得到了状态(?)的同一个实例用默认值

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-05-15 16:41:13

对于简单的情况,您可以在ProfileViewState中使用ProfileViewState而不是MutableStateFlow

类似于:

代码语言:javascript
复制
class ProfileViewState {
    var nick  by mutableStateOf("default nick")
}

在你的创作中:

代码语言:javascript
复制
  Text(text = viewState.value.nick, style = MaterialTheme.typography.h4)
  Button(onClick = { viewState.value.nick= "new nick"}){Text("Update")}

如果要使用MutableStateFlow,就必须观察nick

类似于:

代码语言:javascript
复制
val nick = viewModel.state.value.nick.collectAsState()

Text(text = nick.value, style = MaterialTheme.typography.h4)
Button(onClick = { viewModel.state.value.nick.value  = "new nick"}){Text("Update")}

在这种情况下,您还可以在viewModel中提供一个函数来更新昵称:

代码语言:javascript
复制
class HelloViewModel : ViewModel() {
    //...
   
    fun onNameChange(newName: String) {
        _name.value = newName
    }
}

class ProfileViewState {

    val nick: MutableStateFlow<String> = MutableStateFlow("default nick")
   
    fun onNickChange(newNick: String) {
        nick.value = newNick
    }
}

然后在您的可组合中只需使用:

代码语言:javascript
复制
Button(
     onClick = { viewModel.onNickChange("new nick2")}
){ /*..*/ }
票数 4
EN

Stack Overflow用户

发布于 2021-05-15 17:00:29

这可能是因为您正在使用嵌套的StateFlow,并且只收集外部的,同时更新内部的。我建议采取以下措施:

代码语言:javascript
复制
data class ProfileViewState(val nick: String, ...)

// Update it like:
fun updateNick(nick: String){
     _state.value = _state.value.copy(nick = nick)
}

这样viewModel.state.collectAsState()就可以工作了

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67546600

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档