更改 LiveData 日历的值不会触发观察者

时间:2021-01-01 19:23:09

标签: android kotlin calendar android-livedata observer-pattern

在片段中,我显示来自日历对象的日期。这个日期是从片段的 viewModel 中获得的,它是一个实时日期:

private val _theDate = MutableLiveData<Calendar>()
val theDate: LiveData<Calendar>
    get() = _theDate

在 viewModel 中,我还有一个将 _theDate 添加 1 天的函数

fun goToDayAfter() {
    _theDate.value!!.add(Calendar.DATE, 1)
}

这个函数是在点击同一个fragment的按钮后调用的,它不会触发观察者:

viewModel.theDate.observe(viewLifecycleOwner, androidx.lifecycle.Observer { newDate ->
    displayDate(newDate)
})

有关更多详细信息和调试后,我认为_theDate已更改但未触发观察者,如果我更改为另一个片段并返回新的_theDate已更改。

此外,如果我将方法 goToDayAfter() 更改为:

fun goToDayAfter() {
    val tmp = _theDate.value!!
    tmp.add(Calendar.DATE, 1)
    _theDate.value = tmp
}

有效!

为什么直接修改 _theDate 不会触发观察者?是因为它是一个对象而不是一个前提吗?有没有更好的解决方案来传递 tmp 变量?

1 个答案:

答案 0 :(得分:3)

要触发更新,您必须设置 select csr.CreatedAt, sum(case when sn.name like '%.net%' then csr.JobOffersCount end) as cnt_net, sum(case when sn.name like '%sap%' then csr.JobOffersCount end) as cnt_sap from CompanySkillRegionDemands csr join SkillNames sn on csr.SkillId = sn.SkillId and sn.Language = 'en' group by csr.CreatedAt order by CreatedAt; 的值,就像您发现的那样,即使用:

LiveData

否则,如果您改变(即更改)_theDate.value = ... 指向的值 (LiveData,它无法知道该值已更改!这就是不触发更新的原因。< /p>

首选不可变对象

我建议使用不可变对象并在每次要更改它们时重新创建它们。对于不可变对象,更难遇到这种错误。一个额外的好处是观察 _theDate.value!!.add(Calendar.DATE, 1) 的代码不能改变它。

因此,我会使用 _theDate 而不是 Calendar。如果您在 java.time.LocalDateTime 文件中向 desugar_jdk_libs 添加依赖项,则可以使用它:

build.gradle

在这种情况下,您的代码将如下所示:

coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.1'