当项目添加到LiveData列表时,我需要获得一个Observer事件。但据我所知,只有当我用新列表替换旧列表时,事件才会收到。例如,当我执行下一个操作时:
list.value = mutableListOf(IssuePost(UserEntity(name, email, photoUrl), issueEntity))
观察者获取事件。但当我将项目添加到值中时,观察者是沉默的。你能给我一些建议吗?
我使用Kotlin的扩展函数
使其更容易:
fun <T> MutableLiveData<T>.notifyObserver() {
this.value = this.value
}
然后在任何mutablelivedata
中使用它,如下所示:
fun addIssuePost(issuePost: IssuePost) {
mIssuePostLiveData.value?.add(issuePost)
mIssuePostLiveData.notifyObserver()
}
在内部,LiveData以版本号(存储为int的简单计数器)的形式跟踪每个更改。调用setValue()会增加这个版本,并用新数据更新任何观察者(仅当观察者的版本号小于LiveData的版本时)。
启动此过程的唯一方法似乎是调用setValue()或postValue()。副作用是,如果LiveData的底层数据结构发生了变化(比如向集合中添加了元素),那么将不会发生任何事情来将其传达给观察者。
因此,在向列表中添加一个项目之后,必须调用setValue()。我提供了两种方法,您可以在下面处理这一点。
备选方案1
将列表保留在LiveData之外,并在列表内容更改时使用引用进行更新。
private val mIssuePosts = ArrayList<IssuePost>()
private val mIssuePostLiveData = MutableLiveData<List<IssuePost>>()
fun addIssuePost(issuePost: IssuePost) {
mIssuePosts.add(issuePost)
mIssuePostLiveData.value = mIssuePosts
}
备选方案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
}
这两种解决方案中的任何一种都可以帮助您避免每次修改当前列表以通知观察者时都必须创建一个新列表。
更新:
正如Gnzlt在他的回答中提到的,我使用类似的技术已经有一段时间了,即使用Kotlin扩展函数将LiveData分配给它自己,以简化代码。这基本上是选项2的自动化:)我建议这样做。
在livedata的observe方法中有这样一条评论 在给定所有者的生命周期内将给定的观察者添加到观察者列表中。事件在主线程上分派。如果LiveData已经有数据集,它将传递给观察者。 当我尝试向现有livedata实例添加新的观察者时,如果livedata具有数据集,则new观察者的onChanged方法调用。 有什么办法可以避免这种行为吗?我只是不想被通知新的观察员 SingleLiveEv
我有下面的代码从我的房间数据库的LiveData中获取信息- 出于某种原因,在观察者内部调用submitList不会将项添加到列表中。 我试图在观察者之前添加虚假的测试项目,它工作了,我在调用submitList方法之前记录了模型信息,它打印了有效信息。 我还试图用一个主分发器的协程来结束对submitList的调用,认为这与回调不在主线程中或类似的东西有关,但仍然没有结果。 我错过了什么?一切看
此外,为什么Viewmodel不能观察到它自己的LiveData的变化?
我尝试使用这个实现ViewModel。但观察者从未被调用。 基本上,这个应用程序在SAMPLE_URL上发出网络请求,将JSON转换为列表,并通过BookView显示列表。这个应用程序在没有ViewModel的情况下工作得很好。使用ViewModel,应用程序会运行,但Observer从未被调用,也没有显示任何数据。 我在这里做错了什么? BookActivity类: BookViewModel类
我有一个单独的类来处理数据提取(特别是Firebase),我通常从它返回LiveData对象并异步更新它们。现在我希望将返回的数据存储在ViewModel中,但问题是为了获得所述值,我需要观察从数据提取类返回的LiveData对象。observe方法需要一个LifecycleOwner对象作为第一个参数,但我的ViewModel中显然没有这个对象,而且我知道我不应该在ViewModel中保留对ac
我正在从ViewModel中的Dialog片段更新LiveData值,但无法获取片段中的值。 视图模型: BaseViewModel: 对话框片段: 我从DialogFragment的xml文件中调用viewmodel的resendOTP(contactId:String)方法: 现在,每当我尝试从片段中调用resendOTP响应LiveData时,它都不会被调用: 所以我在这里做错了什么。 编辑