Skip to content

Instantly share code, notes, and snippets.

@NikolaDespotoski
Created December 3, 2017 16:26
Show Gist options
  • Save NikolaDespotoski/76b23572765cd8afb8703e8896aa1803 to your computer and use it in GitHub Desktop.
Save NikolaDespotoski/76b23572765cd8afb8703e8896aa1803 to your computer and use it in GitHub Desktop.
import android.arch.lifecycle.LifecycleOwner
import android.arch.lifecycle.MediatorLiveData
import android.arch.lifecycle.MutableLiveData
import android.arch.lifecycle.Observer
import LoadingState
import io.reactivex.Flowable
import io.reactivex.functions.Action
import io.reactivex.functions.Consumer
import io.reactivex.internal.functions.Functions
/**
* Created by Nikola on 11/4/2017.
*/
open class BaseMediatorLiveData<T> : MediatorLiveData<T>() {
lateinit var loadingLiveData: MutableLiveData<Int>
lateinit var progressLiveData: MutableLiveData<Int>
lateinit var errorLiveData: MutableLiveData<Throwable>
lateinit var progressObserver: Observer<Int>
lateinit var loadingObserver: Observer<Int>
lateinit var errorObserver: Observer<Throwable>
override fun onActive() {
takeIf { this::errorObserver.isInitialized }?.also { errorLiveData = MutableLiveData() }?.addSource(errorLiveData, errorObserver)
takeIf { this::progressObserver.isInitialized }?.also { progressLiveData = MutableLiveData() }?.addSource(progressLiveData, progressObserver)
takeIf { this::loadingObserver.isInitialized }?.also { loadingLiveData = MutableLiveData() }?.addSource(loadingLiveData, loadingObserver)
super.onActive()
}
internal fun errorConsumer() = if (::errorLiveData.isInitialized) errorLiveData.asErrorConsumer() else Functions.ERROR_CONSUMER
internal fun asOnCompleteAction() = Action {
loadingLiveData.postValue(LoadingState.NOT_LOADING)
}
internal fun postLoading(loadingState: Int) {
if (::loadingLiveData.isInitialized) {
loadingLiveData.postValue(loadingState)
}
}
fun observeError(errorObserver: Observer<Throwable>): BaseMediatorLiveData<T> {
[email protected] = errorObserver
return this
}
fun observeLoading(loadingObserver: Observer<Int>): BaseMediatorLiveData<T> {
[email protected] = loadingObserver
return this
}
/**
* @return this BaseMediatorLiveData instance
*/
fun observeProgress(progressObserver: Observer<Int>): BaseMediatorLiveData<T> {
[email protected] = progressObserver
return this
}
/**
* @return Throwable consumer
*/
private fun MutableLiveData<Throwable>.asErrorConsumer() = Consumer<Throwable> {
postLoading(LoadingState.NOT_LOADING)
postValue(it)
}
internal fun <T> BaseMediatorLiveData<T>.asConsumer() = Consumer<T> {
postLoading(LoadingState.NOT_LOADING)
postValue(it)
}
}
fun <T> BaseMediatorLiveData<T>.fromExistingPublisher(flowable: Flowable<T>): BaseMediatorLiveData<T> {
postLoading(LoadingState.LOADING)
flowable.subscribe(asConsumer(), errorConsumer(), asOnCompleteAction())
return this
}
/**
* @param lifecycleOwner LifecycleOwner instance
* @param observer Observer instance that will consume the final result
* @param loading Observer instance that wil consume loading state
* @param error Observer instance that will consume errors
*
*/
fun <T> BaseMediatorLiveData<T>.observe(lifecycleOwner: LifecycleOwner, observer: Observer<T>, loading : Observer<Int>, error: Observer<Throwable>){
loadingObserver = loading
errorObserver = error
observe(lifecycleOwner, observer)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment