基于多个实时数据值的Android逻辑

时间:2018-08-24 18:43:56

标签: android mvvm kotlin android-databinding android-livedata

我正在使用Android数据绑定库通过LiveData进行反应视图

我要回购一份工作清单

var jobsRequest: LiveData<Resource<List<Job>>>
    = Transformations.switchMap(position) { repo.getJobsWithStatus(it) }

然后,基于以上内容,我还有3个LiveData,

首先,检查请求是否已完成

private val requestComplete: LiveData<Boolean>
    = Transformations.map(jobsRequest) { 
        it.status == Status.SUCCESS || it.status == Status.ERROR 
      }

接下来,要转换为没有资源包装器的作业列表

var jobs: LiveData<List<Job>>
    = Transformations.map(jobsRequest) { it.data }

最后,检查该工作清单是否为空

val jobsEmpty: LiveData<Boolean>
    = Transformations.map(jobs) { (it ?: emptyList()).isEmpty() }

在布局中,如果请求尚未完成且作业列表为空,并且需要在我的视图模型中指定此变量,则要显示一个加载微调器

我已经尝试过下面的代码,并且按预期的那样,它不起作用

val spinnerVisible: LiveData<Boolean>
    = Transformations.map(requestComplete) {
        !(requestComplete.value ?: false) && (jobsEmpty.value ?: true)
      }

基于另外2个状态的LiveData变量的正确做法是什么-我想将所有逻辑都保留在视图模型中,而不是活动或布局中。

1 个答案:

答案 0 :(得分:1)

是否需要jobsEmpty观察者?似乎您可以重用jobs

关于您的问题: 为此,有一个MediatorLiveData。它可以满足您的需要:它可以合并多个(以您的情况为准)2个LiveData对象,并可以基于该对象确定另一个livedata值。

一些伪代码:

MediatorLiveData showSpinner = new MediatorLiveData<Boolean>()
showSpinner.addSource(jobsEmpty, { isEmpty ->
    if (isEmpty == true || requestComplete.value == true) {
       // We should show!
       showSpinner.value = true
    }
    // Remove observer again
    showSpinner.removeSource(jobsEmpty);
})
showSpinner.addSource(requestComplete, { isCompleted ->
    if (isCompleted == true && jobsEmpty == true) {
       // We should show!
       showSpinner.value = true
    }
    // Remove observer again
    showSpinner.removeSource(requestComplete);
})
return showSpinner

请注意,您需要返回结果mediatorlivedata,因为这是您感兴趣的布局对象。

此外,您可以查看MediatorLiveData上的文档,其中包含更多示例:https://developer.android.com/reference/android/arch/lifecycle/MediatorLiveData