在 EditText 中使用 Android LiveData 进行操作?

Operations With Android LiveData in EditText?

我有 3 个编辑文本,我必须将前两个中写入的数字相乘,并使用 Android 实时数据使结果显示在第三个上。

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

我尝试过类似的操作,使用 2 个 MutableLiveData 和一个 MediatorLivedata,但我做错了,因为它没有更新第三个 EditText。有人可以帮助我吗?

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

我正在使用 Kotlin,但我接受任何类型的代码,即使是 java。

感谢您的耐心等待和帮助!

此致,马克。

这可能不是您的文字代码,因为它不可编译。您不能传递相同的函数以用作任一源的观察者,因为源类型不同。

您的 onChanged() 函数不使用输入参数,因此您可以删除它并从传递给每个 addSource 调用的 lambda 中调用它。

您还可以使用 Elvis 运算符简化函数的内容。

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
}

请尝试类似的操作,但要注意可空性。接收到的值之一可以为 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()
            }
        }
    )