【发布时间】:2021-02-02 12:41:08
【问题描述】:
我在来自 Google 的 Codelabs 和其他来源的不同示例项目中看到了以下所有场景,并且不完全了解从哪里检索 LiveData 对象的值。
场景 1 - 当前理解:
根据https://developer.android.com/.../viewmodel 的说法,使用 ViewModel 的一个原因是存储/缓存与 UI 相关的数据,这些数据在配置更改后重建相应的 UI 后我想重新使用。
给定以下简化的 ViewModel 和 Repository:第一次调用 updateName() 后,_currentName 的 LiveData 对象包含一个字符串。如果在屏幕旋转后重新构建 UI,则需要显示当前名称的视图通过观察 currentName 来请求它,而 currentName 又返回包含在 _currentName 属性字段中的 LiveData 对象的值。我说的对吗?
视图模型
class NamesViewModel(): ViewModel() {
private val respository = NamesRepository()
private val _currentName: MutableLivedata<String?> = MutableLiveData(null)
val currentName: LiveData<String?> get() = this._currentName
...
// Called as UI event listener.
fun updateName() {
this._currentName.value = this.repository.updateName()
}
}
存储库
class NamesRepository() {
fun updateName(): String {
val nextName: String
...
return nextName
}
}
场景 2:
如果在以下情况下屏幕旋转后重新构建 UI,会发生什么情况? ViewModel 中的 _currentName “观察”存储库中的 currentName,但它仍然是一个属性,因此将其自己的 LiveData 对象存储在其字段中。当视图随后从 ViewModel 请求 currentName 时,将从 ViewModel 中 _currentName 属性的字段中包含的 LiveData 对象中检索该值。这是正确的吗?
视图模型
class NamesViewModel(): ViewModel() {
private val respository = NamesRepository()
private val _currentName: LiveData<String?> = this.repository.currentName
val currentName: LiveData<String?> get() = this._currentName
...
// Called as UI event listener.
fun updateName() {
this.repository.updateName()
}
}
存储库
class NamesRepository() {
private val _currentName: MutableLivedata<String?> = MutableLiveData(null)
val currentName: LiveData<String?> get() = this._currentName
fun updateName() {
val nextName: String
...
this._currentName.value = nextName
}
}
场景 3:
在以下场景中,如果 UI 被重建并且视图从 ViewModel 请求 currentNam,请求的值存储在哪里?我目前的理解是, currentName 回退到存储库中属性 _currentName 的字段。这不违反 ViewModel 存储相关 UI 数据以在配置更改后重新使用的想法吗?在下面的例子中,从存储库而不是 viewModel 中检索值可能没有问题,但是如果存储库本身直接从来自 Room 数据库的 LiveData 对象中检索值呢?每次视图从 viewModel 请求 _currentName 时不会发生数据库访问吗?
我希望有人能更清楚地说明情况,以便了解如何以正确的方式在 viewModel 中缓存 UI 相关数据(或至少了解哪些是不正确的方式)。
视图模型
class NamesViewModel(): ViewModel() {
private val respository = NamesRepository()
val currentName: LiveData<String?> get() = this.repository.currentName
...
// Called as UI event listener.
fun updateName() {
this.repository.updateName()
}
}
存储库
class NamesRepository() {
private val _currentName: MutableLivedata<String?> = MutableLiveData(null)
val currentName: LiveData<String?> get() = this._currentName
fun updateName() {
val nextName: String
...
this._currentName.value = nextName
}
}
【问题讨论】:
标签: android kotlin viewmodel android-livedata