Skip to content

Instantly share code, notes, and snippets.

@kyryloz
Last active April 25, 2019 09:48
Show Gist options
  • Save kyryloz/0f7401bbfd0102c9e0866d9ec80290bd to your computer and use it in GitHub Desktop.
Save kyryloz/0f7401bbfd0102c9e0866d9ec80290bd to your computer and use it in GitHub Desktop.
import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.Transformations
fun <T, R> LiveData<T>.map(mapFunction: (T) -> R): LiveData<R> =
Transformations.map(this) { mapFunction(it) }
fun <T> LiveData<T>.filter(predicate: (T) -> Boolean): LiveData<T> =
MediatorLiveData<T>().apply {
addSource(this@filter) { if (predicate(it)) value = it }
}
fun <T, R> LiveData<T>.switchMap(mapFunction: (T) -> LiveData<R>): LiveData<R> =
Transformations.switchMap(this) { mapFunction(it) }
fun <T> LiveData<T>.distinct(): LiveData<T> =
MediatorLiveData<T>().apply {
this.addSource(this@distinct) { if (it != this.value) this.value = it }
}
fun <A, B> LiveData<A>.zipWith(b: LiveData<B>) =
MediatorLiveData<Pair<A, B>>().apply {
var lastA: A? = null
var lastB: B? = null
fun update() {
val localLastA = lastA
val localLastB = lastB
if (localLastA != null && localLastB != null) {
val newValue = Pair(localLastA, localLastB)
if (value != newValue) {
value = newValue
}
}
}
addSource(this@zipWith) {
lastA = it
update()
}
addSource(b) {
lastB = it
update()
}
}
fun <A, B> LiveData<Resource<A>>.zipLoadingStatus(
liveDataB: LiveData<Resource<B>>
): LiveData<Boolean> =
this
.zipWith(liveDataB)
.map { (resourceA, resourceB) ->
resourceA.status == Resource.Status.LOADING
|| resourceB.status == Resource.Status.LOADING
}
.distinct()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment