【问题标题】:Operations With Android LiveData in EditText?在 EditText 中使用 Android LiveData 进行操作?
【发布时间】:2021-08-07 03:21:26
【问题描述】:

我有 3 个编辑文本,我必须将前两个中写入的数字相乘,并使用 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() }

我尝试了类似的方法,使用 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 中也是如此。

感谢您的耐心和帮助!

最好的问候,马克。

【问题讨论】:

    标签: android kotlin viewmodel android-livedata observers


    【解决方案1】:

    请尝试类似的方法,但请注意可空性。接收到的值之一可以为空

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

    【讨论】:

    • 谢谢!它工作正常,但 EditText 不会实时更新,因为所有三个 editText 都在同一个视图中。仅当我退出视图并返回视图时才会更新。你知道我怎样才能让它在现场工作吗?
    • @qwerty123 这是一个不同的问题。请向我们提供您的活动或片段的代码以及您的 ViewModel,以帮助我们找出您的问题。我相信您更新两个源实时数据的方式存在问题。或者将其作为新问题发布在 Stackoverflow 上会更好
    • 好的,谢谢,我用代码发布了一个新问题:stackoverflow.com/questions/67586779/…
    【解决方案2】:

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

    您的 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
    }
    

    【讨论】:

    • 谢谢!它工作正常,但 EditText 不会实时更新,因为所有三个 editText 都在同一个视图中。仅当我退出视图并返回视图时才会更新。你知道我怎样才能让它在现场工作吗?
    猜你喜欢
    • 2020-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-10
    • 1970-01-01
    • 2015-01-30
    • 1970-01-01
    相关资源
    最近更新 更多