如何将 MediatorLiveData 与抽象源一起使用
How to use MediatorLiveData with an abstract source
我有一个抽象 class,里面有一个 MediatorLiveData
对象。此对象有多个来源,其中之一取决于子项 class,并且在父项 class 中是 abstract
。
在 init
块中添加源会在运行时导致 NullPointerException,因为在 init 块添加源时,它仍然是抽象的(或者我被引导相信)。
有没有一种方法可以使用 abstract
LiveData
作为 MediatorLiveData
的源,而不必在子 class 中设置该源?我只想 override val
并完成它,因为我肯定会忘记在将来的某个时间调用 addSources()
函数。
(我知道这个例子不是做这件事的最有用的方法,但我不想增加不必要的复杂性)
示例:
abstract class MyClass: ViewModel(){
private val _myMediator = MediatorLiveData<String>()
protected abstract val mySource: LiveData<String>
val myObservable: LiveData<String>
get() = _myMediator
// This will cause a NullPointerException at runtime
init{
_myMediator.addSource(mySource){ _myMediator.value = it }
}
//This should work, but requires this to be called in child class
protected fun addSources(){
_myMediator.addSource(mySource){ _myMediator.value = it }
}
}
class myChild: MyClass(){
override val mySource = Transformations.map(myRepository.someData) { it.toString() }
// This is where init { addSources() } would be called
}
阅读 Stachu 的答案后,我决定使用这个,我没有测试但我认为它应该有效:
abstract class MyFixedClass: ViewModel(){
private val _myMediator: MediatorLiveData<String> by lazy{
MediatorLiveData<String>().apply{
addSource(mySource){ this.value = it }
}
}
protected abstract val mySource: LiveData<String>
val myObservable: LiveData<String>
get() = _myMediator
}
class MyChild: MyFixedClass(){
override val mySource = Transformations.map(myRepository.someData) { it.toString() }
}
使用惰性求值如何,例如像这样
abstract class MyClass : ViewModel() {
private val _myMediator = MediatorLiveData<String>()
private val _mySource: LiveData<String> by lazy { mySource() }
protected abstract fun mySource(): LiveData<String>
val myObservable: LiveData<String>
get() = _myMediator
init {
_myMediator.addSource(_mySource) { _myMediator.value = it }
}
}
class myChild : MyClass() {
override fun mySource() = Transformations.map(myRepository.someData) { it.toString() }
}
我有一个抽象 class,里面有一个 MediatorLiveData
对象。此对象有多个来源,其中之一取决于子项 class,并且在父项 class 中是 abstract
。
在 init
块中添加源会在运行时导致 NullPointerException,因为在 init 块添加源时,它仍然是抽象的(或者我被引导相信)。
有没有一种方法可以使用 abstract
LiveData
作为 MediatorLiveData
的源,而不必在子 class 中设置该源?我只想 override val
并完成它,因为我肯定会忘记在将来的某个时间调用 addSources()
函数。
(我知道这个例子不是做这件事的最有用的方法,但我不想增加不必要的复杂性)
示例:
abstract class MyClass: ViewModel(){
private val _myMediator = MediatorLiveData<String>()
protected abstract val mySource: LiveData<String>
val myObservable: LiveData<String>
get() = _myMediator
// This will cause a NullPointerException at runtime
init{
_myMediator.addSource(mySource){ _myMediator.value = it }
}
//This should work, but requires this to be called in child class
protected fun addSources(){
_myMediator.addSource(mySource){ _myMediator.value = it }
}
}
class myChild: MyClass(){
override val mySource = Transformations.map(myRepository.someData) { it.toString() }
// This is where init { addSources() } would be called
}
阅读 Stachu 的答案后,我决定使用这个,我没有测试但我认为它应该有效:
abstract class MyFixedClass: ViewModel(){
private val _myMediator: MediatorLiveData<String> by lazy{
MediatorLiveData<String>().apply{
addSource(mySource){ this.value = it }
}
}
protected abstract val mySource: LiveData<String>
val myObservable: LiveData<String>
get() = _myMediator
}
class MyChild: MyFixedClass(){
override val mySource = Transformations.map(myRepository.someData) { it.toString() }
}
使用惰性求值如何,例如像这样
abstract class MyClass : ViewModel() {
private val _myMediator = MediatorLiveData<String>()
private val _mySource: LiveData<String> by lazy { mySource() }
protected abstract fun mySource(): LiveData<String>
val myObservable: LiveData<String>
get() = _myMediator
init {
_myMediator.addSource(_mySource) { _myMediator.value = it }
}
}
class myChild : MyClass() {
override fun mySource() = Transformations.map(myRepository.someData) { it.toString() }
}