每当其中一个LiveData更新其值时,更新LiveData的值

问题描述 投票:0回答:1

我有一个LiveData,其中包含一个像这样的列表:

val originalSourceLiveaData = MutableLiveData<List<SomeType>>()

现在我有另一个LiveData,它应该表明过滤了originalSourceLiveaData的价值。

val filterLiveData = MutableLiveData<String>()

我想要的是,每当其中一个LiveData改变值时,应该更新结果列表。我尝试过这样的事情:

val filteredListLiveData = MediatorLiveData<List<SomeType>().apply {
    addSource(originalSourceLiveaData) { this.value = filteringMethod() }
    addSource(filterLiveData) { this.value = filteringMethod() }
}

这很好用,但我想知道是否有更好的解决方案。

我的问题是,如果添加了另一个LiveData,我必须将其添加为源,如下所示:

val filteredListLiveData = MediatorLiveData<List<SomeType>().apply {
    addSource(originalSourceLiveaData) { this.value = filteringMethod() }
    addSource(filterLiveData) { this.value = filteringMethod() }
    addSource(anotherSourceLiveData) { 
        this.value = filteringMethod() // this feels like a duplicate 
    }
}

有什么改进的想法吗?提前致谢!

android android-livedata
1个回答
0
投票

您可以使用Kotlin的扩展功能使其更具反应性。

假设你有firstLiveaDatasecondLiveData与相同类型的T。现在,您希望先过滤它们,然后再听取所有更改。

因此,您可以添加以下扩展功能:

  • filter函数将根据给定的谓词函数过滤您的livingata
  • addSources函数将执行添加多个livingata的样板并听取他们的更改
fun <T> LiveData<T>.filter(predicate : (T) -> Boolean): LiveData<T> {
    val mutableLiveData = MediatorLiveData<T>()
    mutableLiveData.addSource(this) {
        if(predicate(it))
            mutableLiveData.value = it
    }
    return mutableLiveData
}

fun <T> MediatorLiveData<T>.addSources(vararg listOfLiveData: LiveData<T>, callback: (T) -> Unit) {
    listOfLiveData.forEach {
        addSource(it, callback)
    }
}

此外,您可以使用LivaData函数将多个具有相同类型的merge对象合并为一个:

fun <T> merge(vararg liveDataList: LiveData<T>): LiveData<T> {
    val mergedLiveData = MediatorLiveData<T>()
    liveDataList.forEach { liveData ->

        liveData.value?.let {
            mergedLiveData.value = it
        }

        mergedLiveData.addSource(liveData) { source ->
            mergedLiveData.value = source
        }
    }
    return mergedLiveData
}

这是一个例子:

fun doSomething() {
    val firstLiveData = MutableLiveData<List<SomeType>>()
    val secondLiveData = MutableLiveData<List<SomeType>>()

    merge(firstLiveData, secondLiveData).filter { someFilterFunction() }.observe(...)
}

如果你有不同类型的LiveData(例如firstLiveData<Int>secondLiveData<String>),你可以简单地添加一个map扩展函数。

© www.soinside.com 2019 - 2024. All rights reserved.