简体   繁体   English

LiveData Observer 在不需要时触发

[英]LiveData Observer triggers when not needed

I have a viewmodel that receives flow as livedata from scenario我有一个视图模型,它从场景中接收流作为实时数据

val state get () = syncScenario.state.asLiveData ()

In the activity, we subscribe to this livedata, some logic happens and used the activityResult在活动中,我们订阅了这个实时数据,发生了一些逻辑并使用了 activityResult

private val resultLauncher = registerForActivityResult (activityResult ()) {result ->
         when (result.resultCode) {
             Activity.RESULT_OK -> sync()
             Activity.RESULT_CANCELED -> return
         }
     }

when we return, we have an observer triggered with the last state and the previous logic with navigation is performed again当我们返回时,我们有一个观察者被最后一个 state 触发,并且再次执行之前的导航逻辑

private val syncStateObserver = Observer<StateInfo?> {
        it?: return@Observer

        when (it) {
            is Guest -> doWhenUserIsGuest()
            is Authorized -> doWhenUserIsAuthorized()
        }
    }

How can you ignore an observer trigger with the same value on return?如何忽略返回值相同的观察者触发器?

There is a popular answer for this.对此有一个流行的答案。 You can wrap your StateInfo with SingleEvent class:您可以使用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
}

So your observer looks like below:所以你的观察者看起来像下面这样:

private val syncStateObserver = Observer<SingleEvent<StateInfo>> {
        it.getContentIfNotHandled()?: return@Observer

        when (it.peek()) {
            is Guest -> doWhenUserIsGuest()
            is Authorized -> doWhenUserIsAuthorized()
        }
}

this url is help me - https://medium.com/androiddevelopers/livedata-with-snackbar-navigation-and-other-events-the-singleliveevent-case-ac2622673150这个 url 对我有帮助 - https://medium.com/androiddevelopers/livedata-with-snackbar-navigation-and-other-events-the-singleliveevent-case-ac2622673150

but doesn't work for livedata.ktx -> liveData{ syncScenario.state.collect { emit(Wrapper(it))} }但不适用于 livedata.ktx -> liveData{ syncScenario.state.collect { emit(Wrapper(it))} }

I solved this by making a method in which I collect data from the flow and put it in my mutable livedata with wrapper from url我通过制作一种方法解决了这个问题,在该方法中我从流中收集数据并将其放入带有包装器的可变实时数据中 url

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM