Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Some fragment observers trigger after pop from back stack although data is not changed

I have some problem in nested fragment in Kotlin. I have nested fragment with ViewModel. After resuming fragment from back button press all observers on viewModel LiveData triggers again although my data does not changed.

First i googled and tried for define observer in filed variable and check if it is initialized then do not observer it again: lateinit var observer: Observer

fun method(){
        if (::observer.isInitialized) return
        observer = Observer{ ... }
        viewModel.x_live_data.observe(viewLifecycleOwner ,observer)
}

So at first enter to fragment it works fine and also after resume it does not trigger again without data change but it does not trigger also on data change! What is going on?

like image 316
Mahdi Avatar asked Dec 06 '19 02:12

Mahdi


People also ask

Why LiveData Observer is being triggered twice?

The second time it is called as soon as Room has loaded the data. Hence, upon the first call the LiveData object is still empty. It is designed this way for good reasons.

Can multiple observers be attached to a live data instance?

All observers will only receive events once they happen! Next use it just as you would regular live data: Multiple observers receive events. In case of same multiple observer problem(fragment back-stack) it is possible to use observeInOnStart() method.

When LiveData observer is called?

1. Ensures your UI matches your data state LiveData follows the observer pattern. LiveData notifies Observer objects when the lifecycle state changes. You can consolidate your code to update the UI in these Observer objects.


1 Answers

LiveData always stores the last value and sends it to each Observer that is registered. That way all Observers have the latest state.

As you're using viewLifecycleOwner, your previous Observer has been destroyed, so registering a new Observer is absolutely the correct thing to do - you need the new Observer and its existing state to populate the new views that are created after you go back to the Fragment (since the original Views are destroyed when the Fragment is put on the back stack).

If you're attempting to use LiveData for events (i.e., values that should only be processed once), LiveData isn't the best API for that as you must create an event wrapper or something similar to ensure that it is only processed once.

like image 116
ianhanniballake Avatar answered Oct 14 '22 18:10

ianhanniballake