【问题标题】:How do I cast custom MutableLiveData to custom LiveData?如何将自定义 MutableLiveData 转换为自定义 LiveData?
【发布时间】:2019-09-13 13:46:19
【问题描述】:

假设有 2 个类:

class MyLiveData:LiveData<Int>()

class MyMutableLiveData:MutableLiveData<Int>()

允许从MutableLiveData 转换为LiveData

val ld1=MutableLiveData<Int>()
val ld2:LiveData<Int> = ld1  //ok

但您不能以这种方式转换自己的实现:

val mutable=MyMutableLiveData()
val immutable:MyLiveData = mutable //type missmatch

我知道 MutableLiveData 扩展 LiveData 这就是为什么它们是可转换的。但我不能让 MyMutableLiveData 扩展 MyLiveData 因为在这种情况下它不会是可变的

有任何解决方法吗?

UPD:我想我需要表现出扩展LiveData的动机。我正在尝试实现MutableLiveDataCollection,它通知的不仅仅是价值通过setValue/postValue 进行更改,但也可以修改值,例如添加新元素。我很惊讶没有针对此的本地解决方案。
无论如何,要观察modify 事件,必须有额外的观察方法。并且此方法必须在不可变部分中,即LiveDataCollection,因为视图会调用它。恕我直言,继承是自然的解决方案。

【问题讨论】:

  • 我的LiveData 的数据类型是ArrayList。我需要特定的观察方法来订阅观察像new items were added to array 这样的事件
  • 你有什么建议?

标签: kotlin android-livedata mutablelivedata


【解决方案1】:

关键思想在于MutableLiveData 类。这个类唯一做的事情是改变setValue/postValue 方法的访问修饰符。我可以做同样的伎俩。因此最终代码将是:

open class LiveDataCollection<K,
                              L:MutableCollection<K>,
                              M:Collection<K>>: LiveData<L>() {
    private var active=false
    private var diffObservers = ArrayList<Observer<M>>()
    fun observe(owner: LifecycleOwner, valueObserver: Observer<L>, diffObserver: Observer<M>) {
        super.observe(owner,valueObserver)
        diffObservers.add(diffObserver)
    }
    protected open fun addItems(toAdd:M) {
        value?.addAll(toAdd)
        if (active)
            for (observer in diffObservers)
                observer.onChanged(toAdd)
    }
    override fun removeObservers(owner: LifecycleOwner) {
        super.removeObservers(owner)
        diffObservers= ArrayList()
    }

    override fun onActive() {
        super.onActive()
        active=true
    }

    override fun onInactive() {
        super.onInactive()
        active=false
    }
}

class MutableLiveDataCollection<K,L:MutableCollection<K>,
                                  M:Collection<K>>: LiveDataCollection<K,L,M>() {
    public override fun addItems(toAdd:M) {
        super.addItems(toAdd)
    }

    public override fun postValue(value: L) {
        super.postValue(value)
    }

    public override fun setValue(value: L) {
        super.setValue(value)
    }
}

【讨论】:

    猜你喜欢
    • 2018-11-29
    • 1970-01-01
    • 1970-01-01
    • 2010-09-26
    • 1970-01-01
    • 1970-01-01
    • 2013-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多