如何从MutableLiveData发出不同的值?

Pra*_*ane 2 android android-livedata mutablelivedata

我观察到观察者的MutableLiveData触发器onChanged,即使为其setValue方法提供了相同的对象实例也是如此。

//Fragment#onCreateView - scenario1
val newValue = "newValue"
mutableLiveData.setValue(newValue) //triggers observer
mutableLiveData.setValue(newValue) //triggers observer

//Fragment#onCreateView - scenario2
val newValue = "newValue"
mutableLiveData.postValue(newValue) //triggers observer
mutableLiveData.postValue(newValue) //does not trigger observer
Run Code Online (Sandbox Code Playgroud)

如果向setValue()/ 提供了相同或等效的实例,是否有办法避免两次通知观察者postValue()

我尝试扩展,MutableLiveData但是没有用。我可能在这里错过了一些东西

class DistinctLiveData<T> : MutableLiveData<T>() {

    private var cached: T? = null

    @Synchronized override fun setValue(value: T) {
        if(value != cached) {
            cached = value
            super.setValue(value)
        }
    }

    @Synchronized override fun postValue(value: T) {
        if(value != cached) {
            cached = value
            super.postValue(value)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Jur*_*lja 33

API中已经有:Transformations.distinctUntilChanged()

不同直到改变

public static LiveData<X> distinctUntilChanged (LiveData<X> source)
Run Code Online (Sandbox Code Playgroud)

LiveData在源 LiveData 值更改之前,创建新对象不会发出值。如果equals()yields ,则认为该值已更改 false

<<剪剩余>>

  • 由于这被标记为可能的仅链接答案,我摘录了一些文档。 (2认同)
  • 值得一提的是,`Transformations.distingUntilChanged()` 最早在 Ver 2.1.0 中可用,但还不是稳定版本!https://developer.android.com/jetpack/androidx/releases/lifecycle#2.1.0-alpha01 (2认同)

Epi*_*rce 6

您可以使用以下魔术来消耗“相同的物品”:

fun <T> LiveData<T>.distinctUntilChanged(): LiveData<T> = MediatorLiveData<T>().also { mediator ->
    mediator.addSource(this, object : Observer<T> {
        private var isInitialized = false
        private var previousValue: T? = null

        override fun onChanged(newValue: T?) {
            val wasInitialized = isInitialized
            if (!isInitialized) {
                isInitialized = true
            }
            if(!wasInitialized || newValue != previousValue) {
                previousValue = newValue
                mediator.postValue(newValue)
            }
        }
    })
}
Run Code Online (Sandbox Code Playgroud)

如果要检查参照相等,则为!==