如何使用数据绑定库从Room数据库观察LiveData更改

时间:2017-11-01 22:30:13

标签: android mvvm data-binding

首次实施房间和数据绑定。

在我的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}"

由于插入会议室数据库并不会导致返回任何内容,因此我无法将numberOfClubs设置为结果。我假设clubs应该跟踪更改?

2 个答案:

答案 0 :(得分:2)

是的,正如您所知,已经有LiveData可识别生命周期。这意味着只要存在生命周期所有者就会观察到它。

即使您已经发布了解决方案,也不应该使用!!一点都不

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)
    }
)

答案 1 :(得分:0)

对我自己有点误解LiveData。为了让LiveData对象开始发送内容,请.observe()。由于LiveData可识别生命周期,.observe()最好在FragmentActivity内调用,因为它引用LifecycleOwner,这必须是传递的第一个参数进入.observe()

我可能没有遵循最佳做法,因为我在ObservableInt ViewModel中设置Activity,但我使用过:

viewModel.clubs
    .observe(this, Observer { clubs ->
        viewModel.numberOfClubs.set(clubs!!.size)
    })