Search code examples
kotlinandroid-livedatamutablelivedata

How do I cast custom MutableLiveData to custom LiveData?


suppose there are 2 classes:

class MyLiveData:LiveData<Int>()

class MyMutableLiveData:MutableLiveData<Int>()

Casting from MutableLiveData to LiveData is permitted:

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

But you can't cast your own implementations this way:

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

I understand that MutableLiveData extends LiveData thats why they are castable.But I can't have MyMutableLiveData extending MyLiveData as it won't be mutable in this case

Are there any workarounds?

UPD:I guess I need to show motivation of extending LiveData.I'm trying to implement MutableLiveDataCollection which notifies not just value changes via setValue/postValue but also value modification like adding new elements.I'm surprised there is no native solution for this.
Anyway to obseve modify events there have to be additional observe method.And this method have to be inside immutable part aka LiveDataCollection because views will call it.Inheritance is natural solution here IMHO.


Solution

  • The key idea sits in the MutableLiveData class.The only thing this class does - is it changes access modifiers on setValue/postValue methods.I can do the same trick.Therefore the final code will be:

    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)
        }
    }