第一次实现机房和数据绑定。
在我的ViewModel:
var numberOfClubs = ObservableInt(0)
private var clubs: LiveData<List<Club>> = clubDao.getAllClubs()然后,在插入Room数据库之后,我尝试获取clubs.value,但每次都会得到一个KotlinNullPointerException。
fun addClubs() {
Observable.fromCallable({
clubDao.insertClubs(listOf(Club(null, "clubName"))
})
.subscribeOn(schedulerFacade.computation)
.subscribe(
{
numberOfClubs.set(clubs.value!!.size) <--- Kotlin NPE
},
{ error ->
logWrapper.e("MainViewModel", error.message!!)
clubError.set(true)
})
}在我的XML中,我调用:android:text="@{viewModel.numberOfClubs}"。
由于插入到Room数据库不会导致返回任何内容,所以我无法设置带有结果的numberOfClubs。我认为clubs应该跟踪更改吗?
发布于 2017-11-04 15:13:49
是我对LiveData的一点误解。为了让一个LiveData对象开始发射东西,就是要对它进行.observe()。因为LiveData知道生命周期,所以最好从Fragment或Activity中调用.observe(),因为它具有对LifecycleOwner的引用,这必须是传递到.observe()的第一个参数。
我可能没有遵循最佳实践,因为我在ViewModel中从ViewModel中设置了一个Activity,但是我使用了:
viewModel.clubs
.observe(this, Observer { clubs ->
viewModel.numberOfClubs.set(clubs!!.size)
})发布于 2017-11-04 15:53:16
是的,正如您已经发现的,LiveData是生命周期感知的。这意味着只要livecycle在场,它就会进行观察。
即使你已经发布了解决方案,你也不应该使用!完全没有。
viewModel.clubs.observe(this, {
it?.let {
viewModel.numberOfClubs.set(it.size)
}
)是在分配接收列表大小之前执行空检查的正确方法。
顺便说一句,如果您想在布局中获得项目大小,您应该使用
text="@{viewModel.clubsList.size() + ``}" 并观察一个列表,而不是使用
val clubsList = ObservableArrayList<..>()
viewModel.clubs.observe(this, {
it?.let {
viewModel.clubsList.set(it)
}
)https://stackoverflow.com/questions/47064687
复制相似问题