如何在Kotlin中简单地向MediatorLiveData添加另一个源?

时间:2019-06-30 18:25:16

标签: kotlin android-livedata

我想在MediatorLiveData中合并多个数据源。不幸的是,还没有很多例子。所以在我的ViewModel中,

//all lists have been declared before

val playerList = MediatorLiveData<List<Player>>()

init {
    playerList.addSource(footballPlayerList) { value ->
        playerList.value = value
    }
    playerList.addSource(basketballPlayerList) { value ->
        playerList.value = value
    }
}

但是显然,这将始终覆盖playerList的当前值。我的意思是我可以使用诸如_playerList之类的辅助变量来构建一些变通的解决方法,但是也许有一个更简单的解决方案?

2 个答案:

答案 0 :(得分:0)

已经做了很多研究。我发现了。这是一个例子

fun blogpostBoilerplateExample(newUser: String): LiveData<UserDataResult> {

val liveData1 = userOnlineDataSource.getOnlineTime(newUser)
val liveData2 = userCheckinsDataSource.getCheckins(newUser)

val result = MediatorLiveData<UserDataResult>()

result.addSource(liveData1) { value ->
    result.value = combineLatestData(liveData1, liveData2)
}
result.addSource(liveData2) { value ->
    result.value = combineLatestData(liveData1, liveData2)
}
return result
}

实际的数据组合是通过类似的单独的CombineLatestData方法完成的

private fun combineLatestData(
    onlineTimeResult: LiveData<Long>,
    checkinsResult: LiveData<CheckinsResult>
): UserDataResult {

val onlineTime = onlineTimeResult.value
val checkins = checkinsResult.value

// Don't send a success until we have both results
if (onlineTime == null || checkins == null) {
    return UserDataLoading()
}

// TODO: Check for errors and return UserDataError if any.

return UserDataSuccess(timeOnline = onlineTime, checkins = checkins)
}

答案 1 :(得分:0)

这是一个简单的例子

class MergeMultipleLiveData : ViewModel() {

private val fictionMenu: MutableLiveData<Resource<RssMenu>> = MutableLiveData()
private val nonFictionMenu: MutableLiveData<Resource<RssMenu>> = MutableLiveData()
val allCategoryMenus: MediatorLiveData<Resource<RssMenu>> = MediatorLiveData()

init {
    getFictionMenus()
    getNonFictionMenus()
    getAllCategoryMenus()
}

private fun getAllCategoryMenus() = viewModelScope.launch(Dispatchers.IO) {
    allCategoryMenus.addSource(fictionMenu) { value ->
        allCategoryMenus.value = value
    }
    allCategoryMenus.addSource(nonFictionMenu) { value ->
        allCategoryMenus.value = value
    }
}

private fun getFictionMenus() = viewModelScope.launch(Dispatchers.IO) {
    fictionMenu.postValue( // todo )
}

private fun getNonFictionMenus() = viewModelScope.launch(Dispatchers.IO) {
    nonFictionMenu.postValue( // todo )
}

}

在你的片段中,你可以观察为;

viewModel.allCategoryMenus.observe(viewLifecycleOwner) {
        // todo
    }