ViewModel有3个变量,彼此依赖,并在Android上更新UI



我正在制作一个示例应用程序,发现了一些我不知道如何解决的问题
我有一个包含3个变量的ViewModel
其中1个是操作的结果,因此它取决于其他:

private val _a = MutableLiveData<Int>().apply {
value = 0
}
val a: LiveData<Int> = _a
private val _b = MutableLiveData<Int>().apply {
value = 0
}
val b: LiveData<Int> = _b
private val _c = MutableLiveData<Int>().apply {
value = 100
}
val c: LiveData<Int> = _c
fun updateA(value: Int) {
val cvalue = 100 - _a.value!! - _b.value!!
_a.postValue(value)
_c.postValue(cvalue)
}

结果是UI上显示的数字(使用observe(viewLifecycleOwner)等…(是错误的:总是有一个与1不同或相似的数字。

UI具有用于ab的2个SeekBar,以及显示abc的值的3个TextView。目前,我只向a添加了一个更改侦听器,它通过progress作为参数调用updateA。所以此刻b总是0。发生的情况是,当a变成2时(因为我将SeekBar句柄移动到那个位置(,c的值不是98,而是99,所以总和是101而不是100

我想这可能取决于线程在调用postValue时决定如何更新这些值,但我在文档中没有找到任何内容
我测试了另一种方法,即当小部件调用更改侦听器时计算所有值,它运行得很好,但我认为这应该不是正确的方法
有人能给我一些建议吗
问候

缺少一些信息来给您一个完整的答案,但您可以将第三个LiveData声明为其他两个的转换,为此,您通常使用MediatorLiveData来调解多个源之间的值。

class YourViewModel : ViewModel() {

// Assuming a and b to be what you've declared
val c: LiveData<Int> = MediatorLiveData().apply {
addSource(a) { mostRecentA ->
value = yourOperation(mostRecentA, b.value) // or default value
}
addSource(b) { mostRecentB ->
value = yourOperation(a.value, mostRecentB) // or default value
}
}
// If these functions are called from the main thread 
// it's safe to just assign the value
fun setA(value: Int) { _a.value = value }
fun setB(value: Int) { _b.value = value }
fun yourOperation(aVal: Int?, bVal: Int?) = 100 - (aVal?:0) - (bVal?:0)
}

相关内容

最新更新