Created
September 17, 2019 16:01
-
-
Save cuub/aff2a441506ccf89e82c5d006aa04789 to your computer and use it in GitHub Desktop.
A lifecycle-aware observable that sends the event only once to all observers. Similar o SingleLiveEvent but supporting multiple observers.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class LiveDataShotOnce<T> : MutableLiveData<T>() { | |
private val observerWrapperMap = WeakHashMap<Observer<in T>, ObserverWrapper<in T>>() | |
@MainThread | |
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) { | |
val observerWrapper = ObserverWrapper(observer) | |
observerWrapperMap[observer] = observerWrapper | |
super.observe(owner, observerWrapper) | |
} | |
@MainThread | |
override fun observeForever(observer: Observer<in T>) { | |
observerWrapperMap[observer] = ObserverWrapper(observer) | |
super.observeForever(observer) | |
} | |
@MainThread | |
override fun removeObserver(observer: Observer<in T>) { | |
val wrapper: ObserverWrapper<in T>? = if (observer is ObserverWrapper) observer else observerWrapperMap[observer] | |
if (wrapper != null) { | |
observerWrapperMap -= wrapper.originalObserver | |
super.removeObserver(wrapper) | |
} | |
} | |
@MainThread | |
override fun setValue(value: T) { | |
observerWrapperMap.values.forEach(ObserverWrapper<in T>::setPending) | |
super.setValue(value) | |
} | |
private class ObserverWrapper<ObsW>(val originalObserver: Observer<ObsW>) : Observer<ObsW> { | |
private var pending = false | |
fun setPending() { | |
pending = true | |
} | |
override fun onChanged(t: ObsW) { | |
if (!pending) return | |
pending = false | |
originalObserver.onChanged(t) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment