LiveData Observer 在不需要时触发
LiveData Observer triggers when not needed
我有一个视图模型从场景中接收流作为实时数据
val state get () = syncScenario.state.asLiveData ()
在activity中,我们订阅了这个实时数据,发生了一些逻辑并使用了activityResult
private val resultLauncher = registerForActivityResult (activityResult ()) {result ->
when (result.resultCode) {
Activity.RESULT_OK -> sync()
Activity.RESULT_CANCELED -> return
}
}
当我们 return 时,我们有一个用最后一个状态触发的观察者,并且再次执行之前的导航逻辑
private val syncStateObserver = Observer<StateInfo?> {
it?: return@Observer
when (it) {
is Guest -> doWhenUserIsGuest()
is Authorized -> doWhenUserIsAuthorized()
}
}
如何忽略 return 上具有相同值的观察者触发器?
对此有一个流行的答案。你可以用 SingleEvent
class:
包装你的 StateInfo
open class SingleEvent<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
}
因此您的观察者如下所示:
private val syncStateObserver = Observer<SingleEvent<StateInfo>> {
it.getContentIfNotHandled()?: return@Observer
when (it.peek()) {
is Guest -> doWhenUserIsGuest()
is Authorized -> doWhenUserIsAuthorized()
}
}
但不适用于 livedata.ktx -> liveData{ syncScenario.state.collect { emit(Wrapper(it))} }
我通过制作一种方法解决了这个问题,在该方法中,我从流程中收集数据并将其放入带有来自 url
的包装器的可变实时数据中
我有一个视图模型从场景中接收流作为实时数据
val state get () = syncScenario.state.asLiveData ()
在activity中,我们订阅了这个实时数据,发生了一些逻辑并使用了activityResult
private val resultLauncher = registerForActivityResult (activityResult ()) {result ->
when (result.resultCode) {
Activity.RESULT_OK -> sync()
Activity.RESULT_CANCELED -> return
}
}
当我们 return 时,我们有一个用最后一个状态触发的观察者,并且再次执行之前的导航逻辑
private val syncStateObserver = Observer<StateInfo?> {
it?: return@Observer
when (it) {
is Guest -> doWhenUserIsGuest()
is Authorized -> doWhenUserIsAuthorized()
}
}
如何忽略 return 上具有相同值的观察者触发器?
对此有一个流行的答案。你可以用 SingleEvent
class:
StateInfo
open class SingleEvent<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
}
因此您的观察者如下所示:
private val syncStateObserver = Observer<SingleEvent<StateInfo>> {
it.getContentIfNotHandled()?: return@Observer
when (it.peek()) {
is Guest -> doWhenUserIsGuest()
is Authorized -> doWhenUserIsAuthorized()
}
}
但不适用于 livedata.ktx -> liveData{ syncScenario.state.collect { emit(Wrapper(it))} }
我通过制作一种方法解决了这个问题,在该方法中,我从流程中收集数据并将其放入带有来自 url
的包装器的可变实时数据中