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