Skip to content

Instantly share code, notes, and snippets.

@Zhuinden
Created May 21, 2020 03:34
Show Gist options
  • Save Zhuinden/50ec75542ca22084094b949542908be1 to your computer and use it in GitHub Desktop.
Save Zhuinden/50ec75542ca22084094b949542908be1 to your computer and use it in GitHub Desktop.
EventEmitter + LiveEvent to replace LiveData<Event<T>>
private class LiveEvent<T> constructor(
private val eventSource: EventSource<T>,
private val lifecycleOwner: LifecycleOwner,
private val observer: EventSource.EventObserver<T>
) : LifecycleObserver {
init {
if (lifecycleOwner.lifecycle.currentState.isAtLeast(Lifecycle.State.INITIALIZED)) {
lifecycleOwner.lifecycle.addObserver(this)
}
}
private var isActive: Boolean = false
private var notificationToken: EventSource.NotificationToken? = null
private fun shouldBeActive(): Boolean {
return lifecycleOwner.lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)
}
private fun disposeObserver() {
lifecycleOwner.lifecycle.removeObserver(this)
}
@OnLifecycleEvent(Lifecycle.Event.ON_ANY)
fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
if (lifecycleOwner.lifecycle.currentState == Lifecycle.State.DESTROYED) {
stopListening()
disposeObserver()
return
}
checkIfActiveStateChanged(shouldBeActive())
}
private fun checkIfActiveStateChanged(newActive: Boolean) {
if (newActive == isActive) {
return
}
val wasActive = isActive
isActive = newActive
val isActive = isActive
if (!wasActive && isActive) {
stopListening()
notificationToken = eventSource.startListening(observer)
}
if (wasActive && !isActive) {
stopListening()
}
}
private fun stopListening() {
notificationToken?.stopListening()
notificationToken = null
}
}
fun <T> EventSource<T>.observe(lifecycleOwner: LifecycleOwner, eventObserver: (T) -> Unit) {
LiveEvent(this, lifecycleOwner, EventSource.EventObserver<T> { event -> eventObserver.invoke(event) })
}
class MyViewModel : BaseFragment(R.layout.my_fragment) {
private val viewModel: MyViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.events.observe(viewLifecycleOwner) { event: MyViewModel.Events ->
when (event) {
is MyViewModel.Events.NewWordAdded -> showToast("Added ${event.word}")
}.safe()
}
}
}
class MyViewModel: ViewModel() {
sealed class Events {
data class NewWordAdded(val word: String) : Events()
}
private val eventEmitter = EventEmitter<Events>()
val events: EventSource<Events>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment