如何将两个可变实时数据的结果合并为一个

时间:2019-07-30 11:45:07

标签: android kotlin android-livedata mutablelivedata

我的ViewModel中有两个变量,这些变量由用户使用按钮控制。他可以通过单击适当的按钮来减少或增加值。

val age = MutableLiveData<Int>().apply { value = 0 }

val weight = MutableLiveData<Double>().apply { value = 0.0 }

现在,仅当两个变量的值都大于0时,我才希望启用保存按钮。该怎么做?我曾考虑过在ViewModel correctData中创建另一个LiveData变量,或者以某种方式在Activity中观察年龄和体重变量,但是我需要帮助,因为我不知道该怎么做。

谢谢您的帮助。

更新

我创建了MediatorLiveData,它几乎可以正常工作,几乎是因为它无法检测两个来源是否都提供了真实值,但是没有检测到任何真实值。

private val _correctData = MediatorLiveData<Boolean>().apply {
        value = false
        addSource(age) { x -> x?.let { value = x > 0 } }
        addSource(repeats) { x -> x?.let { value = x > 0 } }
    }

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

尝试使用MediatorLiveData,它旨在将多个LiveData合并为一个流 https://developer.android.com/reference/android/arch/lifecycle/MediatorLiveData

由于您要合并两种不同的类型,因此我建议创建一个新类来容纳这些值:

data class AgeAndWeight(val age: Int = 0, val weight: Double = 0.0)

然后创建一个类型为MediatorLiveData的变量:

val ageAneWeight = MediatorLiveData<AgeAndWeight>().apply { AgeAndWeight() }

实现您的合并功能:

fun merge() {
        ageAneWeight.addSource(age) { value ->
            val previous = ageAneWeight.value
            ageAneWeight.value = previous?.copy(age = value)
        }
        ageAneWeight.addSource(weight) { value ->
            val previous = ageAneWeight.value
            ageAneWeight.value = previous?.copy(weight = value)
        }
    }

并观察您的新实时数据:

fun observe() {
    ageAneWeight.observe(this, Observer {
        if (it.age != 0 && it.weight > 0.0) {
            //do whatever you want
        }
    })
}

答案 1 :(得分:0)

使用另外2个布尔变量来跟踪两个LiveData是否都返回true。

private val _correctData = MediatorLiveData<Boolean>().apply {
        var weightFlag = false
        var ageFlag = false
        value = false
        addSource(age) { x -> x?.let { 
                            ageFlag = x > 0 
                            if (weightFlag && ageFlag) {
                                value = true
                            }
                        } }
        addSource(weight) { x -> x?.let { 
                            weightFlag = x > 0 
                            if (weightFlag && ageFlag) {
                                value = true
                            }
                        } }
    }