[英]Collect state from StateFlow
我在 Compose 和 MVVM 架構中開發應用程序。 我有每個屏幕的視圖 state 的 viewModel。 視圖模型:
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
}
}
}
State:
class ProfileViewState {
val nick: MutableStateFlow<String> = MutableStateFlow("default nick")
}
當用戶按下按鈕時,我會更改 state 中“nick”的值。
_state.value.nick.value = "new nick"
我想在我的視圖中觀察 state 並在它們更改時自動更新數據
@Composable
fun ProfileScreen() {
val viewModel: ProfileViewModel = viewModel()
val viewState by viewModel.state.collectAsState()
}
TextView 我嘗試在其中顯示“nick”值
Text(text = viewState.nick.value, style = MaterialTheme.typography.h4)
問題是當我更改 state 中的數據時,屏幕沒有反應也沒有更新。 當我打開 ProfileScreen 時,我得到了具有默認值的相同 state(?) 實例
對於簡單的情況,您可以在MutableStateFlow
中使用mutableStateOf("default nick")
而不是ProfileViewState
。
就像是:
class ProfileViewState {
var nick by mutableStateOf("default nick")
}
在你的可組合物中:
Text(text = viewState.value.nick, style = MaterialTheme.typography.h4)
Button(onClick = { viewState.value.nick= "new nick"}){Text("Update")}
如果你想使用MutableStateFlow
你必須觀察nick
。
就像是:
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 中提供 function 來更新昵稱:
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
}
}
然后在你的可組合中使用:
Button(
onClick = { viewModel.onNickChange("new nick2")}
){ /*..*/ }
這可能是因為您正在使用嵌套的StateFlow
並且只收集外部的,同時更新內部的。 我建議轉到以下實現:
data class ProfileViewState(val nick: String, ...)
// Update it like:
fun updateNick(nick: String){
_state.value = _state.value.copy(nick = nick)
}
這樣viewModel.state.collectAsState()
應該可以工作
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.