简体   繁体   中英

Operations With Android LiveData in EditText?

I have 3 editext and I have to multiply the numbers written in the first two, and make the result appear live on the third using Android Livedata.

viewModel.num1.observe(this,
    Observer { newNum1-> binding.ediText1.text = newNum1.toString() }

viewModel.num2.observe(this,
    Observer { newNum2-> binding.ediText2.text = newNum2.toString() }

viewModel.num3.observe(this,
    Observer { newNum3-> binding.ediText3.text = newNum3.toString() }

I tried something like this, with 2 MutableLiveData and one MediatorLivedata, but i did something wrong because it didn't update live the third EditText. Could someone help me?

class MyViewModel : ViewModel() {
    private var num1 = MutableLiveData<Int>();
    private var num2 = MutableLiveData<Double>();
    private var mun3 = MediatorLiveData<Double>();

    num3.addSource(num1, this::onChanged);
    num3.addSource(num2, this::onChanged);
  
    
    private fun onChanged(x : Double) {
        var a = num1.value
        var b = num2.value

        if (a== null)
            a= 0;
        if (b== null)
            b= 0.0;
        
        num3.setValue(a * b);
    }
}

I'm using Kotlin but i accept any kind of code, even in java.

Thank you for your patience and help!

Best regards, Mark.

That might not be your literal code, because it's not compileable. You can't pass the same function to be used as the observer for either source, since the source types are different.

Your onChanged() function doesn't use the input parameter, so you can remove that and call it from a lambda you pass to each addSource call.

You can also simplify the content of your function by using Elvis operators.

private val num1 = MutableLiveData<Int>()
private val num2 = MutableLiveData<Double>()
private val num3 = MediatorLiveData<Double>().apply {
    addSource(num1) { onChanged() }
    addSource(num2) { onChanged() }
}

private fun onChanged() {
    val a = num1.value ?: 0
    val b = num2.value ?: 0.0
    num3.value = a * b
}

Please try something like that, but be aware of nullability. One of received values can be null

fun <A, B> LiveData<A>.combineWith(b: LiveData<B>): LiveData<Pair<A?, B?>> =
MediatorLiveData<Pair<A?, B?>>().apply {
    var lastA: A? = this@combineWith.value
    var lastB: B? = b.value

    addSource(this@combineWith) {
        lastA = it
        value = Pair(lastA, lastB)
    }

    addSource(b) {
        lastB = it
        value = Pair(lastA, lastB)
    }
}

viewModel.num1
    .combineWith(viewModel.num2)
    .observe(
        this, 
        Observer { (first, second) -> 
            if (first != null && second != null) {
                 someEditText.text = (first * second).toString()
            }
        }
    )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM