class ActionViewModel : ViewModel() {
private val onCreateLiveData: MutableLiveData<Event<String>> = MutableLiveData()
fun observeOnCreateEvent(): LiveData<Event<String>> = onCreateLiveData
fun onCreateCollectionClick(message: String) {
this.onCreateLiveData.value = Event(message)
}
}
事件 Package 类实现如下所示:
/*Used as a wrapper for data that is exposed via a LiveData that represents an
event.*/
open class Event<out T>(private val content: T) {
var hasBeenHandled = false
private set // Allow external read but not write
/**
* Returns the content and prevents its use again.
*/
fun getContentIfNotHandled(): T? {
return if (hasBeenHandled) {
null
} else {
hasBeenHandled = true
content
}
}
/**
* Returns the content, even if it's already been handled.
*/
fun peekContent(): T = content
}
现在我们可以观察到这样的片段:
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
actionViewModel = ViewModelProviders.of(requireActivity()).get(ActionViewModel::class.java)
actionViewModel.observeOnCreateEvent()
.observe(this, Observer {
it?.takeIf { userVisibleHint }?.getContentIfNotHandled()?.let {
//DO what ever is needed
}
})
}
5条答案
按热度按时间jum4pzuy1#
最后,我找到了一个解决这个问题的方法:我不得不放弃那些只发出一个事件的实时数据,因为它不能按照我需要的方式工作。
相反,我使用了简单的可变实时数据,它发出一个事件对象,该对象 Package 了一个数据,如Jose Alcérreca编写的article的最后一段所示。
我在视图页中显示片段,因此此时只有一个可见片段。
我的视图模型如下所示:
事件 Package 类实现如下所示:
现在我们可以观察到这样的片段:
如果片段当前对用户可见,则FragmentuserVisibleHint属性将返回True。由于我们此时仅显示一个片段,因此这对我们有效。这意味着片段将仅访问事件数据(如果可见)。
另外,Event Package 器的实现只允许读取一次值,因此,下次Observer获取此事件时,其值将为null,我们将忽略它。
结论:这样,我们模拟的是仅通知最后订阅的观察者的单个事件实时数据。
qeeaahzv2#
如果你使用Kotlin,你可以用Flow替换
LiveData
。StateFlow可以用来替换常规的LiveData
,而SharedFlow可以用来处理无状态事件。它还将为你提供null safety和Flow
自带的所有运算符和配置。迁移在here等地方进行了描述,下面是一个基本示例:
视图模型:
活动:
请注意,
lifecycleScope
需要相应的ktx dependency。Herer's更多阅读关于
Flow
在Android.5t7ly7z53#
我精心设计了一个解决方案,请随意查看https://github.com/ueen/LiveEvent
ivqmmu1c4#
我创建了一个库来处理在处理事件驱动的数据场景时可能遇到的最常见情况
https://github.com/javaherisaber/LiveX
它包含以下类型的类:
| 实时数据|实时事件|OneShot实时事件|单个实时事件|
| - ------|- ------|- ------|- ------|
| 可以注册多个观察者,所有观察者都会根据生命周期接收事件|可以注册多个观察者,每个观察者只能接收事件一次|只有一个观察者只能注册和接收事件一次|可以注册多个观察者,只有第一个观察者接收事件|
xjreopfe5#
我在LD扩展中找到了解决方案:
此的用法: