在内部,LiveData 将每个更改作为版本号(存储为 int 的简单计数器)进行跟踪。调用 setValue() 会增加此版本,并使用新数据更新任何观察者(仅当观察者的版本号小于 LiveData 的版本时)。
看来启动此过程的唯一方法是调用 setValue() 或 postValue()。副作用是,如果 LiveData 的底层数据结构发生了变化(例如向集合添加元素),则不会发生任何事情来将此信息传达给观察者。
因此,在将项目添加到列表后,您必须调用 setValue()。我在下面提供了两种解决此问题的方法。
Option 1
将列表保留在 LiveData 之外,并在列表内容发生更改时使用引用进行更新。
private val mIssuePosts = ArrayList<IssuePost>()
private val mIssuePostLiveData = MutableLiveData<List<IssuePost>>()
fun addIssuePost(issuePost: IssuePost) {
mIssuePosts.add(issuePost)
mIssuePostLiveData.value = mIssuePosts
}
Option 2
通过 LiveData 跟踪列表,并在列表内容发生更改时使用其自己的值更新 LiveData。
private val mIssuePostLiveData = MutableLiveData<MutableList<IssuePost>>()
init {
mIssuePostLiveData.value = ArrayList()
}
fun addIssuePost(issuePost: IssuePost) {
mIssuePostLiveData.value?.add(issuePost)
mIssuePostLiveData.value = mIssuePostLiveData.value
}
这些解决方案中的任何一个都应该可以帮助您不必在每次修改当前列表只是为了通知观察者时创建一个新列表。
UPDATE:
我已经使用类似的技术有一段时间了,正如 Gnzlt 在他的回答中提到的那样,使用 Kotlin 扩展函数将 LiveData 分配给自身以简化代码。这本质上是选项 2 的自动化:) 我建议这样做。