Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get result of two mutablelivedata into one

I have two variables in my ViewModel which are controlled by user with buttons. He can decrement or increment value by click on proper button.

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

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

Now I want enable save button only if value of both variables are greater than 0. How to do that? I thought about create another LiveData variable in ViewModel correctData or observe age and weight variable in Activity in some way, but I need help, because I don't know how to do it.

Thank you for help.

UPDATE

I created MediatorLiveData and it's almost working, almost because it doesn't detect if both sources give true value but if there is any true value.

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

Any ideas?

like image 331
Remzo Avatar asked Jul 30 '19 11:07

Remzo


2 Answers

Try using MediatorLiveData, it is designed to merge several LiveData into a single stream https://developer.android.com/reference/android/arch/lifecycle/MediatorLiveData

Since you're going to merge two different types, I'd recommend creating a new class to hold these values:

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

Then create a variable with type MediatorLiveData:

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

Implement your merge function:

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)
        }
    }

And observe your new live data:

fun observe() {
    ageAneWeight.observe(this, Observer {
        if (it.age != 0 && it.weight > 0.0) {
            //do whatever you want
        }
    })
}
like image 54
Stanislav Shamilov Avatar answered Sep 29 '22 13:09

Stanislav Shamilov


Use another 2 boolean variables that keep track of whether both LiveData has returned 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
                            }
                        } }
    }

like image 21
Chrisvin Jem Avatar answered Sep 29 '22 12:09

Chrisvin Jem