Created
December 3, 2017 16:26
-
-
Save NikolaDespotoski/76b23572765cd8afb8703e8896aa1803 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
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