Kotlin的Nullability和LiveData

lig*_*igi 12 android kotlin android-livedata android-architecture-components

我想将LiveData与Kotlin一起使用,并且值不应为null.你怎么处理这个?也许LiveData的包装?在这里寻找好的模式..作为一个例子:

class NetworkDefinitionProvider : MutableLiveData<NetworkDefinition>() {
    val allDefinitions = mutableListOf(RinkebyNetworkDefinition(), MainnetNetworkDefinition(), RopstenNetworkDefinition())

    init {
        value = allDefinitions.first()
    }

    fun setCurrent(value: NetworkDefinition) {
        setValue(value)
    }
}
Run Code Online (Sandbox Code Playgroud)

我知道访问时值不会为空 - 但我总是要检查null或者让这些丑陋!

ice*_*ail 10

我很少改进回答幸运编码器.此实现根本不接受空值.

class NonNullMutableLiveData<T: Any>(initValue: T): MutableLiveData<T>() {

    init {
        value = initValue
    }

    override fun getValue(): T {
        return super.getValue()!!
    }

    override fun setValue(value: T) {
        super.setValue(value)
    }

    fun observe(owner: LifecycleOwner, body: (T) -> Unit) {
        observe(owner, Observer<T> { t -> body(t!!) })
    }

    override fun postValue(value: T) {
        super.postValue(value)
    }    
}
Run Code Online (Sandbox Code Playgroud)


The*_*der 8

我不知道这是否是最好的解决方案,但这是我想出来的和我使用的:

class NonNullLiveData<T>(private val defaultValue: T) : MutableLiveData<T>() {

    override fun getValue(): T = super.getValue() ?: defaultValue

    fun observe(owner: LifecycleOwner, body: (T) -> Unit) {
        observe(owner, Observer<T> {
            body(it ?: defaultValue)
        })
    }
}
Run Code Online (Sandbox Code Playgroud)

创建字段:

val string = NonNullLiveData("")
Run Code Online (Sandbox Code Playgroud)

观察它:

viewModel.string.observe(this) {
    // Do someting with the data
}
Run Code Online (Sandbox Code Playgroud)

  • 这样做的缺点是,如果有人将`null`放入你的`NonNullLiveData`中,你会向你的观察者发出一个完全错误的值(`defaultValue`).可能取决于您的情况,但如果有人将null放入非空位置,我宁愿崩溃. (2认同)

Dav*_*man -2

我创建了一个扩展属性。它不是非常漂亮,但非常简单。

val <T> LiveData<T>.valueNN
    get() = this.value!!
Run Code Online (Sandbox Code Playgroud)

用法

spinner.loading = myLiveData.valueNN.homeState.loading
Run Code Online (Sandbox Code Playgroud)

我不同意附加“NN”作为一个好的命名约定,但这超出了问题的范围:)

  • 不要这样做。简单地强制解包底层值是危险的,因为“this.value”可能为空。只有当您在 _setters_ 中强制执行不可空性时,您才能像其他答案所建议的那样安全地强制展开。 (9认同)