在onStart的每个片段上触发livedata观察事件

时间:2020-09-30 12:56:19

标签: android kotlin fragment android-livedata mutablelivedata

我在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方法时都不触发观察者回调。

我想念什么?

非常感谢!

2 个答案:

答案 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中)或保留最后看到的值(难以保留)来进行操作,但是想法