有没有更好的方法将私有 MutableLiveData 公开为 ViewModel 的 LiveData。 [Android, 科特林]
Is there a better way to expose private MutableLiveData as LiveData for an ViewModel. [Android, Kotlin]
在下面的示例中,我想像这样公开一个 Int 列表:
val test: LiveData<List<Int>>
get() = _test as LiveData<List<Int>>
private var _test = MutableLiveData(mutableListOf<Int>())
或另一种风格:
private var _test2 = MutableLiveData(mutableListOf<Int>())
val test2 = _test2 as LiveData<List<Int>>
两者都有效,但总是存在未经检查的转换。
Unchecked cast: MutableLiveData<MutableList<Int>!> to LiveData<List<Int>>
有更好的方法吗?
澄清一下:
通过使用 emptyList,用法可能如下所示:
class MainViewModel : ViewModel() {
val test: LiveData<List<Int>> get() = _test
private var _test = MutableLiveData(emptyList<Int>())
init {
val myPrivateList = mutableListOf<Int>()
myPrivateList.add(10)
myPrivateList.add(20)
_test.value = myPrivateList
}
}
我希望找到一种无需额外列表 (myPrivateList) 的方法,如下所示:
class MainViewModel : ViewModel() {
val test: LiveData<List<Int>> get() = _test
private var _test = MutableLiveData(emptyList<Int>())
init {
_test.value?.apply {
add(1)
add(2)
add(3)
}
}
}
您可以使用 emptyList<Int>()
或 listOf<Int>()
创建 MutableLiveData
避免未经检查的转换:
val test: LiveData<List<Int>> get() = _test
private var _test = MutableLiveData(emptyList<Int>())
如果您的代码只是真实用例的示例,请记住您始终可以在 MutableList
上使用 .toList()
。
我知道我的回答来得太晚了,这并不是这个使用 mutableListOf 到 List 的特定问题的答案。尽管如此,希望它对寻找从现在开始如何将 MutableLiveData 公开为 LiveData 的答案的人有用。
只需在您的 BaseViewModel 中定义这个棘手的 Kotlin 扩展(如果您没有,可以将其设为私有并在需要使用它的 ViewModel 中定义):
protected val <T> LiveData<T>.mutable: MutableLiveData<T>
get() = this as MutableLiveData<T>
现在,当您创建 LiveData 对象时,按以下方式定义它:
val liveData: LiveData<Int> = MutableLiveData()
所以现在您将能够在 ViewModel 中轻松便捷地访问可变 LiveData:
liveData.mutable.postValue(1)
而您的观察者会将对象视为 LiveData<> 并且无法访问 .mutable 扩展名,因为它只能在 ViewModels 中访问。
没有私有 _ LiveData,没有复制 LiveData 对象。一切都清楚了 easy-to-use.
在下面的示例中,我想像这样公开一个 Int 列表:
val test: LiveData<List<Int>>
get() = _test as LiveData<List<Int>>
private var _test = MutableLiveData(mutableListOf<Int>())
或另一种风格:
private var _test2 = MutableLiveData(mutableListOf<Int>())
val test2 = _test2 as LiveData<List<Int>>
两者都有效,但总是存在未经检查的转换。
Unchecked cast: MutableLiveData<MutableList<Int>!> to LiveData<List<Int>>
有更好的方法吗?
澄清一下:
通过使用 emptyList,用法可能如下所示:
class MainViewModel : ViewModel() {
val test: LiveData<List<Int>> get() = _test
private var _test = MutableLiveData(emptyList<Int>())
init {
val myPrivateList = mutableListOf<Int>()
myPrivateList.add(10)
myPrivateList.add(20)
_test.value = myPrivateList
}
}
我希望找到一种无需额外列表 (myPrivateList) 的方法,如下所示:
class MainViewModel : ViewModel() {
val test: LiveData<List<Int>> get() = _test
private var _test = MutableLiveData(emptyList<Int>())
init {
_test.value?.apply {
add(1)
add(2)
add(3)
}
}
}
您可以使用 emptyList<Int>()
或 listOf<Int>()
创建 MutableLiveData
避免未经检查的转换:
val test: LiveData<List<Int>> get() = _test
private var _test = MutableLiveData(emptyList<Int>())
如果您的代码只是真实用例的示例,请记住您始终可以在 MutableList
上使用 .toList()
。
我知道我的回答来得太晚了,这并不是这个使用 mutableListOf 到 List 的特定问题的答案。尽管如此,希望它对寻找从现在开始如何将 MutableLiveData 公开为 LiveData 的答案的人有用。
只需在您的 BaseViewModel 中定义这个棘手的 Kotlin 扩展(如果您没有,可以将其设为私有并在需要使用它的 ViewModel 中定义):
protected val <T> LiveData<T>.mutable: MutableLiveData<T>
get() = this as MutableLiveData<T>
现在,当您创建 LiveData 对象时,按以下方式定义它:
val liveData: LiveData<Int> = MutableLiveData()
所以现在您将能够在 ViewModel 中轻松便捷地访问可变 LiveData:
liveData.mutable.postValue(1)
而您的观察者会将对象视为 LiveData<> 并且无法访问 .mutable 扩展名,因为它只能在 ViewModels 中访问。
没有私有 _ LiveData,没有复制 LiveData 对象。一切都清楚了 easy-to-use.