每当你在LiveData上调用.observe()
时,Observer就会接收到LiveData的最后一个值,这在某些情况下可能有用,但在我的情况下就没用了。
1.无论何时调用.observe()
,我都希望Observer只接收将来的LiveData更改,而不是它在调用.observe()
时保存的值。
1.一个LiveData示例可能有多个Observer。我希望它们在发生LiveData更新时都能接收到更新。
1.**我希望每个观察者只使用一次LiveData更新。**我认为这只是第一个要求的重新措辞,但我的头已经旋转,我不确定它。
在谷歌搜索这个问题时,我发现了两种常用的方法:
1.将数据 Package 在LiveData<SingleEvent<Data>>
中,并检查SingleEvent
类是否已被使用。
1.扩展MediatorLiveData
并使用查找图(如果观察者已获得事件)
这些方法的示例可在此处找到:https://gist.github.com/JoseAlcerreca/5b661f1800e1e654f07cc54fe87441af#gistcomment-2783677https://gist.github.com/hadilq/f095120348a6a14251a02aca329f1845#file-liveevent-kthttps://gist.github.com/JoseAlcerreca/5b661f1800e1e654f07cc54fe87441af#file-event-kt
不幸的是,这些例子没有一个能满足我的所有需求。大多数时候,问题是任何新的观察者在订阅时仍然会收到最后一个LiveData值。这意味着当用户在屏幕之间导航时,已经显示的Snackbar会一次又一次地显示。
为了给予您了解我正在谈论的内容/正在编写的代码:
我遵循Android架构组件的LiveData MVVM设计:
- 2 ListFragment显示了一个条目列表。
- 他们使用相同ViewModel类的2个示例观察UI相关LiveData。
- 用户可以删除这样的ListFragment中的条目,删除是通过ViewModel调用
Repository.delete()
完成的 - 视图模型观察
RepositoryEvents
的存储库。
因此,当删除完成时,存储库通知ViewModel,ViewModel通知ListFragment。
现在,当用户切换到第二个ListFragment时,将发生以下情况:
- 创建第二个片段并在其ViewModel上调用
.observe()
- 创建ViewModel并调用存储库上的
.observe()
- 存储库将其当前
RepositoryEvent
发送到ViewModel - ViewModel将相应的UI事件发送到片段
- Fragment显示了在其他地方发生的删除的确认Snackbar。
下面是一些简化的代码:
片段:
viewModel.dataEvents.observe(viewLifecycleOwner, Observer { showSnackbar() })
viewModel.deleteEntry()
视图模型:
val dataEvents: LiveData<EntryListEvent> = Transformations.switchMap(repository.events, ::handleRepoEvent)
fun deleteEntry() = repository.deleteEntry()
private fun handleRepoEvent(event: RepositoryEvent): LiveData<EntryListEvent> {
// convert the repository event to an UI event
}
存储库:
private val _events = MutableLiveData<RepositoryEvent>()
val events: LiveData<RepositoryEvent>
get() = _events
fun deleteEntry() {
// delete it from database
_events.postValue(RepositoryEvent.OnDeleteSuccess)
}
3条答案
按热度按时间6kkfgxo01#
2021年更新:
使用协程库和Flow,现在通过实现
Channels
可以非常容易地实现这一点:vd8tlhqk2#
对我来说,问题解决了这个:
事件 Package 类,用于保存事件相关数据(从google示例复制)
接下来,我创建事件观察器类,它处理数据检查(null等):
和事件处理程序类,以简化从视图模型的访问:
示例:
在ViewModel类中:
在活动/片段中:
开始观察:
创建事件:
wfveoks03#
创建了一个基本的密封类标志,需要:
然后可以在不同的片段上观察到
或者使用具有相同目的的
MutableLiveData
的子类来单独处理它们。