livedata observer called each time when back on fragment

I have fragment1, from which I go to fragment2. The problem is that I can't go back to fragment1 from fragment2 This is how I handle a button click

val onClickLiveData = MutableLiveData<OnClick>()

fun onClick() {
    onClickLiveData.value = OnClick.CLICK
}

This is how I handle transition to fragment2

   private fun subscribeToClickCallbacks() {
    viewModel.onClickLiveData.observe(viewLifecycleOwner, Observer {
            findNavController().navigate(R.id.action_home_fragment_to_repositories_fragment)
    })
}

I process the transition back like this

 navController.popBackStack()

With the help of debug, I found out that with each transition to fragment1, livedata is called and instantly opens fragment2.

How can the problem be solved? I would be grateful for every answer.

Upvotes: 4

Views: 1593

Answers (1)

Mitesh Vanaliya
Mitesh Vanaliya

Reputation: 2611

If live data is observer multiple times use SingleEvent for handle this case. Create one global class for SingleLiveData like this.

class SingleLiveEvent<T> : MutableLiveData<T>() {

    private val mPending = AtomicBoolean(false)

    @MainThread
    override fun observe(owner: LifecycleOwner, observer: Observer<T>) {

        if (hasActiveObservers()) {
            Log.w(TAG, "Multiple observers registered but only one will be notified of changes.")
        }

        // Observe the internal MutableLiveData
        super.observe(owner, object : Observer<T> {
            override fun onChanged(t: T?) {
                if (mPending.compareAndSet(true, false)) {
                    observer.onChanged(t)
                }
            }
        })
    }

    @MainThread
    override fun setValue(t: T?) {
        mPending.set(true)
        super.setValue(t)
    }

    /**
     * Used for cases where T is Void, to make calls cleaner.
     */
    @MainThread
    fun call() {
        setValue(null)
    }

    companion object {

        private val TAG = "SingleLiveEvent"
    }
}

Now use this class like this,

val onClickLiveData = SingleLiveEvent<OnClick>()

Upvotes: 3

Related Questions