Android 为什么调用两次时会忽略Livedata setValue?
我有下面的ViewModel,其中包含可变的LiveDataAndroid 为什么调用两次时会忽略Livedata setValue?,android,kotlin,android-livedata,android-jetpack,android-viewmodel,Android,Kotlin,Android Livedata,Android Jetpack,Android Viewmodel,我有下面的ViewModel,其中包含可变的LiveDatadata和另一个LiveDataones,它是从data派生的,只有当data.number等于1时,它才会更新其值 class DummyViewModel : ViewModel() { private val data = MutableLiveData<Dummy>() val ones = data.mapNotNull { it.takeIf { it.number == 1 } }
data
和另一个LiveDataones
,它是从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
}
class DummyViewModel:ViewModel(){
private val data=MutableLiveData()
val ones=data.mapNotNull{it.takeIf{it.number==1}
初始化{
data.value=Dummy(1,“初始”)
doSomething()
}
有趣的事{
data.value=Dummy(2,“做点什么”)
}
}
数据类虚拟(val编号:Int,val文本:String)
fun LiveData.mapNotNull(映射器:(T)->Y?):LiveData{
val mediator=MediatorLiveData()
mediator.addSource(此){item->
val mapped=映射器(项目)
如果(映射!=null){
mediator.value=mapped
}
}
返回调解人
}
在我的片段中,我观察到了个。但是,如果我执行doSomething
,我不会在片段中收到任何更新。如果我不执行doSomething
,则虚拟Init
将正确地出现在ones
中,我将收到一个更新
这里发生了什么?为什么ones
是空的,我怎样才能克服这个问题?也许我遗漏了什么,但这种行为似乎是我所期待的
让我们试着按顺序重现这两种情况
不使用doSomething():
创建Livedata
添加Dummy(1,“Init”)
开始监听片段:因为数字是1
,所以它会通过你的过滤器,片段会收到它
使用doSomething():
创建Livedata
添加Dummy(1,“Init”)
添加Dummy(2,“做点什么”)
(LiveData
只保留最后一个值,因此如果没有人观察,第一个值就会丢失)
开始在片段中侦听:因为数字是2
,所以该值将被过滤,而片段将不接收任何内容
有点离题:像这样为ViewModel案例编写测试总是好的,因为您将能够隔离问题并快速找到真正的原因
编辑:还要注意,您的筛选器仅用于观察,在将值放入LiveData
时不会应用它,您对此it.takeIf{it.number==1}有何期望
?@StanislavBondar我希望的只在对象的number
属性为1
时才更新其值。这当然只是为了演示。@StanislavBondar让我吃惊的是,如果调用了doSomething
,则第一个data.value=Dummy(1,“Init”)
没有设置。