我具有以下具有MutableLiveData data
的ViewModel和另一个从ones
派生的LiveData data
,该方式只有在data.number
等于1时才更新其值。
class DummyViewModel : ViewModel() {
private val data = MutableLiveData<Dummy>()
val ones = data.mapNotNull { it.takeIf { it.number == 1 } }
init {
data.value = Dummy(1, "Init")
doSomething()
}
fun doSomething() {
data.value = Dummy(2, "Do something")
}
}
data class Dummy(val number: Int, val text: String)
fun <T, Y> LiveData<T>.mapNotNull(mapper: (T) -> Y?): LiveData<Y> {
val mediator = MediatorLiveData<Y>()
mediator.addSource(this) { item ->
val mapped = mapper(item)
if (mapped != null) {
mediator.value = mapped
}
}
return mediator
}
我在片段中观察到ones
。但是,如果执行doSomething
,则片段中不会收到任何更新。如果我不执行doSomething
,则在Init
中正确存在虚拟ones
,并且我收到更新。
这里发生了什么?为什么ones
为空,如何解决此问题?
也许我丢失了一些东西,但是这种行为似乎是我所期望的...
让我们尝试顺序再现这两种情况。
没有doSomething():
Livedata
Dummy(1, "Init")
1
,它会通过您的过滤器,片段会接收到它使用doSomething():
Livedata
Dummy(1, "Init")
Dummy(2, "Do something")
(LiveData
仅保留最后一个值,因此,如果没有人注意,则第一个值会丢失)0
,因此该值将被过滤且片段不接收任何内容有点题外话:针对这样的ViewModel案例编写测试总是很好的,因为您将能够隔离问题并迅速找到真正的原因。