Shopify / livedata-ktx

Kotlin extension for LiveData, chaining like RxJava
MIT License
468 stars 29 forks source link

MutableLiveDataKtx is not subtype of MutableLiveData #22

Open opryzhek opened 5 years ago

opryzhek commented 5 years ago

There are places where MutableLiveData is required, for example in two way data binding. It may be better to make MutableLiveDataKtx a subtype of MutableLiveData as these dependencies are hard to change. Downside of this will be code duplication and the fact that MutableLiveDataKtx would not be subtype of LiveDataKtx anymore. I can make a pull request if you consider this as a good idea.

henrytao-me commented 5 years ago

Hi @opryzhek Thanks for your question. Code duplication is one of the thing I would like to avoid in the first place. I will look into it to see if there are any other approaches.

opryzhek commented 5 years ago

I've run through the code and found out that all extension methods like filter and map are already duplicated for LiveDataKtx, MutableLiveDataKtx and MediatorLiveDataKtx so we can just move some LiveDataKtx methods to separate interface. This way there would be almost zero additional code duplication. Same could be done to MediatorLiveDataKtx.


package com.ronasit.apptemplate.ui

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData

interface ILiveDataKtx<T> {
    val safeValue: T?
    fun getValue(): T
}

open class LiveDataKtx<T> : LiveData<T>(), ILiveDataKtx<T> {

    override val safeValue: T? get() = super.getValue()

    @Suppress("RedundantOverride")
    override fun setValue(value: T) {
        super.setValue(value)
    }

    @Suppress("UNCHECKED_CAST")
    override fun getValue(): T {
        return super.getValue() as T
    }

    @Suppress("RedundantOverride")
    override fun postValue(value: T) {
        super.postValue(value)
    }
}

open class MutableLiveDataKtx<T>: MutableLiveData<T>(), ILiveDataKtx<T> {
    override val safeValue: T? get() = super.getValue()

    @Suppress("UNCHECKED_CAST")
    override fun getValue(): T {
        return super.getValue() as T
    }
    @Suppress("RedundantOverride")
    override fun setValue(value: T) {
        super.setValue(value)
    }

    @Suppress("RedundantOverride")
    override fun postValue(value: T) {
        super.postValue(value)
    }
}