【问题标题】:Android Logic Based On Multiple Live Data Values基于多个实时数据值的 Android 逻辑
【发布时间】:2019-01-31 06:27:46
【问题描述】:

我正在使用 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 变量的正确做法是什么 - 我想将所有逻辑保留在视图模型中,而不是在活动或布局中。

【问题讨论】:

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


    【解决方案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

    【讨论】:

    • 感谢您的回答!我真的希望有一个更优雅的解决方案,但这确实有道理。只是为了确认一下,showSpinner.removeSource(liveData1); 应该是showSpinner.removeSource(jobsEmpty);?如果我希望值继续更新,我应该省略这一行吗?
    • 是的,第一个应该是jobsEmpty,第二个应该是requestCompleted。我会在答案中更新它:)
    • 是的,这也是正确的!如果您想继续收听,可以省略removeSource
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-28
    • 1970-01-01
    • 2011-05-02
    • 2018-08-06
    • 2016-05-21
    相关资源
    最近更新 更多