我正在制作一个示例应用程序,发现了一些我不知道如何解决的问题
我有一个包含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具有用于a
和b
的2个SeekBar
,以及显示a
、b
和c
的值的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)
}