Kotlin中的可观察数组,可知道何时更改数组的elt值

时间:2018-08-22 21:37:23

标签: kotlin

我的目标:我有一个公开的简单课程

val reds = IntArray(10)
val greens = IntArray(10)
val blues = IntArray(10)
val lums = IntArray(10)

如果有人修改了任何红色值,我想更新lum值。

myObj.reds[5] = 100 // Should update myObj.lums[5] = reds[5]+greens[5]+blues[5]

问题在于by Delegates.observable似乎仅用于var对象-没有提及“并且,如果您修改数组的元素,这将被触发”

也许这是不可能的,我必须通过getter和setter进行所有修改-但是我宁愿有一些触发,如可观察的!

2 个答案:

答案 0 :(得分:1)

您将不得不使用自定义类,IntArray被映射到原始int[]数组,因此它没有提供任何地方来插入回调-像您的示例一样更改值({{1} })您只知道何时返回数组,但此后无法控制更改。

例如,您可以创建如下类:

myObj.reds[5] = 100

操作符函数使您可以使用与直接访问相同的语法从基础数组获取值。构造函数中的class IntArrayWrapper(size: Int, val setterObs : ((index: Int, value: Int) -> Unit)? = null){ val field = IntArray(size) val size get() = field.size operator fun iterator() = field.iterator() operator fun get(i: Int) : Int { return field[i] } operator fun set(i: Int, value: Int){ field[i] = value setterObs?.invoke(i, value) } } 参数可让您传递setter方法的“观察者”:

setterObs

请注意,这有一定的局限性,因为您将无法自由使用val reds = IntArrayWrapper(10){index, value -> println("$index changed to $value") invalidateLums(index) // method that modifies lums or whatever you need } val a = reds[2] // getter usage reds[3] = 5 // setter usage that triggers the setter observer callback reds.field[4] = 3 // set value in backing array directly, allows modification without setter callback 扩展方法而不引用后退IntArray,也无法以field的形式传递此类论点。

答案 1 :(得分:0)

我不知道这是否是解决问题的最干净的方法,但是您可以使用ObservableListFX observable collections):

var numbers: ObservableList<Int> = FXCollections.observableArrayList()
numbers.addListener(ListChangeListener<Int> {
    //Do things on change
})

但是正如我提到的,通过添加这些集合,您正在将FX组件混合到您的应用程序中,我不知道它是否需要,甚至是否可以在android等各种平台上运行!