关于UI layer和单向数据流(UDF)的问题。我们有DetailFragment
和EditText
:
- 当用户打开现有详细信息时,文本从
StateFlow<DetailUiState>
开始由ViewModel
填充。 - 现在用户更改文本,
DetailFragment
发送新文本到ViewModel
,更新UI状态,并由于collect
片段接收更新的状态。因此,片段调用setText
,触发再次向ViewModel
发送相同的文本。 - 如果我们在接收新文本时没有更新UI状态,对于任何配置更改(屏幕旋转),片段在重新创建时接收旧文本值。
如何走出这样的怪圈?
data class DetailUiState(
val text: String
)
class DetailViewModel {
private val _uiState = MutableStateFlow(DetailUiState("first text"))
val uiState = _uiState.asStateFlow()
fun onTextChanged(newValue: String) {
_uiState.value = DetailUiState(newValue)
}
}
class DetailFragment {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
repeatOnStartedLatest(viewModel.uiState) { // flow.collect shortcut
binding.editText.setText(it.text)
}
binding.editText.doAfterTextChanged {
viewModel.onTextChanged(binding.editText.getTextAsString())
}
}
}
1条答案
按热度按时间58wvjzkj1#
处理这个问题的一个更好的方法是使用双向数据绑定特性。
在ViewModel类中有一个字段,例如:
在片段的布局文件中:
现在,从
Fragment
类传递ViewModel引用和生命周期所有者: