Android LiveData prevent receive the last value on observe

后端 未结 12 1305
自闭症患者
自闭症患者 2020-11-27 04:41

Is it possible to prevent LiveData receive the last value when start observing? I am considering to use LiveData as events.

For example eve

12条回答
  •  一向
    一向 (楼主)
    2020-11-27 05:33

    Faced the same problem, and I created some simple kotlin extention functions which can solve the problem easily.

    Usage as below:

    val liveData = MutableLiveData()
    liveData.value = "Hello"
    
    val freshResult = mutableListOf()
    val normalResult = mutableListOf()
    
    liveData.observeForeverFreshly(Observer {
        freshResult.add(it)
    })
    
    liveData.observeForever(Observer {
        normalResult.add(it)
    })
    
    liveData.value = "World"
    
    assertEquals(listOf("World"), freshResult)
    assertEquals(listOf("Hello", "World"), normalResult)
    

    Basic source code is explained as bllow.

    For some more detail (to support some special situations for example MediatorLiveData returned from Transformations.map), you can view it in github : livedata-ext

    FreshLiveData.kt

    fun  LiveData.observeFreshly(owner: LifecycleOwner, observer: Observer) { 
        // extention fuction to get LiveData's version, will explain in below.
        val sinceVersion = this.version()
        this.observe(owner, FreshObserver(observer, this, sinceVersion))
    }
    
    fun  LiveData.observeForeverFreshly(observer: Observer, skipPendingValue: Boolean = true) {
        val sinceVersion = this.version()
        this.observeForever(FreshObserver(observer, this, sinceVersion))
    }
    
    // Removes the observer which has been previously observed by [observeFreshly] or [observeForeverFreshly].
    fun  LiveData.removeObserverFreshly(observer: Observer) {
        this.removeObserver(FreshObserver(observer, this, 0))
    }
    
    class FreshObserver(
        private val delegate: Observer,
        private val liveData: LiveData<*>,
        private val sinceVersion: Int
    ) : Observer {
    
        override fun onChanged(t: T) {
            if (liveData.version() > sinceVersion) {
                delegate.onChanged(t)
            }
        }
    
        override fun equals(other: Any?): Boolean {
            if (this === other) return true
            if (javaClass != other?.javaClass) return false
            if (delegate != (other as FreshObserver<*>).delegate) return false
            return true
        }
    
        override fun hashCode(): Int {
            return delegate.hashCode()
        }
    }
    
    

    Becasue we need to access LiveData's pcakage visibile methond getVersion() for comparasion, so create a class in package android.arch.lifecycle or androidx.lifecycle (AndroidX):

    LiveDataHiddenApi.kt

    package androidx.lifecycle
    
    fun LiveData<*>.version(): Int {
        return this.getVersion()
    }
    

提交回复
热议问题