Liveata наблюдать событие, запускаемое в каждом фрагменте onStart

У меня проблемы с LiveData.

У меня есть 3 фрагмента A (menuFragment), B (doThingsFragment), C (displayMessageFragment). Мы можем перейти от A к B, от B к C и, наконец, от C к A.

В методе onStart doThingsFragment я наблюдаю LiveData From doThingsViewModel и перехожу к 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, и я перехожу к фрагменту C до того, как фрагмент B даже отобразится.

Поскольку значение _message не изменилось, я не ожидаю, что вызовет обратный вызов наблюдателя каждый раз при вызове метода doThingFragment.onStart ...

Что мне не хватает?

Большое спасибо !


person AubinCheD    schedule 30.09.2020    source источник


Ответы (2)


Так ведут себя liveata, если вам нужно событие получателя только один раз, Google или stackoverflow о SingleLiveData

person i30mb1    schedule 30.09.2020

LiveData работает по шаблону Observer, где что-то регистрируется как наблюдатель, и каждый раз, когда наблюдаемый объект изменяется, он получает уведомление. Это стоит читать документацию по этому поводу:

Добавляет данного наблюдателя в список наблюдателей в течение срока жизни данного владельца. События отправляются в основном потоке. Если у LiveData уже есть набор данных, он будет доставлен наблюдателю.

Когда данные меняются, пока владелец [LifecycleOwner, например Activity] не активен, он не будет получать никаких обновлений. Если он снова станет активным, он автоматически получит последние доступные данные.

Это важные моменты: когда вы регистрируетесь для observe данных, вы сразу получаете уведомление о самом последнем значении (если оно есть), не только при изменении. Таким образом, вы не можете полагаться на срабатывание обратного вызова как на сигнал о том, что вам нужно перейти с B на C.

Что вам действительно нужно сделать, зависит от логики вашего приложения, от того, как вы можете определить разницу между только что отображенным фрагментом B, вот значение, и теперь мне нужно показать только что отображаемый фрагмент C и фрагмент B, вот значение, но я случайно знаю, что на этот раз мне не нужно показывать фрагмент C. Вы можете сделать что-то, установив флаг initialised при первом получении данных (может потребоваться сохранить это состояние в onSaveInstanceState) или удерживая последнее увиденное значение (сложнее сохранить), но вы понимаете идею

person cactustictacs    schedule 30.09.2020