如何在 Kotlin 中创建可观察的列表

14

每当我的列表中添加新元素时,我想要更新我的文本.. 我尝试使用以下代码来实现..

var myList: MutableList<ArrayList<String>> by Delegates.observable(mutableListOf(), onChange = { _, _, new ->
    Constants.debug("Value Changed")
})

但似乎不起作用...有什么想法吗?

3个回答

11

这段代码无法正常运行是因为可观察的代理只会监视对 变量 的更改,而不会监视储存在该变量中的对象。因此,当列表发生更改时,变量仍然指向同一列表,并且可观察的代理无法知道任何更改。要观察到更改,您需要一些实际观察列表内容的方式,这不是 Kotlin 或 Java 默认提供的。你需要一种可观察的列表。

或者,您可以使用标准列表(而不是可变列表),并在每次需要更改列表时,用新版本的列表替换它。这样,您就可以像想要的那样监听更改,但可能需要调整使用该列表的许多其他代码。


啊,那就说得通了。谢谢。 - Adolf Dsilva
3
有点晚了,不过您可以在自定义类中包装一个 Collection 实现,并覆盖 get/remove 方法。这样您就可以触发您的监听器了。 - Niels
1
使用不可变对象的想法非常棒。Kotlin使得在列表上创建新列表变得容易。顺便说一下,您的列表对并发问题更加健壮。 - Alexander Knauf

10
您可以使用类似以下的方式:

您可以使用如下代码:

class ObservableList<T>(private val wrapped: MutableList<T>): MutableList<T> by wrapped, Observable() {
    override fun add(element: T): Boolean {
        if (wrapped.add(element)) {
            setChanged()
            notifyObservers()
            return true
        }
        return false
    }
}

非常有趣,谢谢 :) 我不知道委托可以这样使用。 - ProjectDelta
如果您正在引用java.util.Observable,那么这已经被弃用了。 - Akito

3

我很晚才发布,但开发了一个提供可观测集合的库。

目前包括以下集合:

列表
ArrayList
LinkedList
Stack
Vector

映射
ArrayMap
ConcurrentHashMap
LinkedHashMap
TreeMap
WeakHashMap

队列
ArrayBlockingQueue
ArrayDeque
DelayDeque
LinkedBlockingQueue
LinkedTransferQueue
PriorityBlockingQueue
Queue
SynchronousQueue

集合
HashSet
LinkedHashSet
TreeSet

如果时间允许或有需求,将添加更多内容。

你可以在https://github.com/theblitz/ObservableCollections找到它,并且可通过gradle on jcenter()进行安装:

implementation 'il.co.theblitz:observablecollections:1.2.0'


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接