我在LiveData方面遇到问题。
我有3个片段A(menuFragment),B(doThingsFragment),C(displayMessageFragment)。 我们可以从A移到B,从B移到C,最后从C移到A。
在doThingsFragment的onStart方法上,我从doThingsViewModel观察LiveData,并在此值更改时移至displayMessageFragment。
doThingsViewModel:
private var _message : MutableLiveData<String> = MutableLiveData()
var message : LiveData<String> = _message
fun someFunction() {
_message.value = "blablabla"
}
doThingsFragment:
override fun onStart() {
super.onStart()
mViewModel!!.message.observe(
viewLifecycleOwner,
Observer<String>
{
msg ->
if(!msg.isNullOrEmpty() && mViewModel!!.toastType.value != null){
val args = Bundle()
args.putString("message", msg)
Navigation.findNavController(requireView()).navigate(R.id.mountUnmountValidationFragment, args)
}
})
}
我第一次更新_message效果很好(我们按预期从B转到C)。 但是,当我再次尝试从A移到B时,我们再次进入doThingsFragment观察者回调,并且在片段B甚至显示之前,我都移至片段C。
由于_message值未更改,我希望每次调用doThingFragment.onStart方法时都不触发观察者回调。
我想念什么?
非常感谢!
答案 0 :(得分:0)
这是实时数据的行为方式,如果您仅需要一次接收器事件,则Google或关于SingleLiveData
的stackoverflow
答案 1 :(得分:0)
LiveData
在观察者模式下工作,其中某个事物注册为观察者,并且每次它观察的事物发生变化时,都会得到通知。值得reading the docs on this:
将给定的观察者添加到给定所有者的生命周期内的观察者列表中。事件在主线程上调度。 如果LiveData已经具有数据集,它将被发送给观察者。
当所有者[
LifecycleOwner
(例如,Activity
]未处于活动状态,因此不会收到任何更新。如果再次变为活动状态,它将自动接收最新的可用数据。
这些很重要-当您向observe
注册数据时,您会立即收到最新值(如果有的话)的通知,不仅是发生更改的情况,。因此,您不能依赖于该回调触发作为您需要从B
移至C
的信号。
您实际需要执行的操作取决于您的应用逻辑,如何区分“刚刚显示的片段B,这是一个值,现在我需要显示片段C”和“刚刚显示的片段B,这是一个值,但是我碰巧知道我这次不需要显示片段C”。您可以通过在第一次接收到一些数据时设置initialised
标志(可能需要将该状态保留在onSaveInstanceState
中)或保留最后看到的值(难以保留)来进行操作,但是想法