Search code examples
androidkotlinviewmodelandroid-livedataobservers

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.


Solution

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