Skip to content

Instantly share code, notes, and snippets.

@kobeumut
Created April 21, 2019 08:24
Show Gist options
  • Star 25 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save kobeumut/edb3edd9a2ae9abf6984a42bb2de0441 to your computer and use it in GitHub Desktop.
Save kobeumut/edb3edd9a2ae9abf6984a42bb2de0441 to your computer and use it in GitHub Desktop.
Android Livedata Observe Once Only (Kotlin)
fun <T> LiveData<T>.observeOnce(lifecycleOwner: LifecycleOwner, observer: Observer<T>) {
observe(lifecycleOwner, object : Observer<T> {
override fun onChanged(t: T?) {
observer.onChanged(t)
removeObserver(this)
}
})
}
//Using
liveData.observeOnce(this, Observer<Password> {
if (it != null) {
// do something
}
})
val liveData = viewModel.showSnackBar("Hi everyone")
liveData.observe(this, object: Observer<String> {
override fun onChanged(text: String?) {
liveData.removeObserver(this)
}
})
@DavidJH2
Copy link

DavidJH2 commented Aug 1, 2021

Great, thanks for the reply!

@mohamedmohamedtaha
Copy link

Good Solution David, that Only work for me. All other solution not work for me and I didn't know why.

@badrnezhad
Copy link

@kobeumut Thank you for this useful code

@JeelPatel231
Copy link

thanks for the solution, however for non-nullable variables with initial value, or for patterns with removing observer on certain conditions, this is helpful

fun <T> LiveData<T>.observeUntil(
    owner: LifecycleOwner,
    predicate: (T) -> Boolean,
    observer: (T) -> Unit
) {
    observe(owner, object: Observer<T> {
        override fun onChanged(value: T) {
            if(predicate(value)) {
                removeObserver(this)
            }
            observer(value)
        }
    })
}

this can be used as:

val mutLiveData = MutableLiveData(0)

mutLiveData.observeUntil(viewLifecycleOwner, { it == 10}) {
    /* code goes here... */
}

@DavidJH2
Copy link

DavidJH2 commented Jun 2, 2023

Nice!

@hitesh-dhamshaniya
Copy link

I have implemented that but when the device configuration changes get the result again. what could we do in that case?

set flag on config change will cost a lot as I have implemented that in many places so, I am looking for optimal solutions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment