传递LiveData取值而非ViewModel时DataBinding不更新问题
问题成因
核心原因:两种绑定方式的观察对象完全不同
第一种绑定方式是将整个ViewModel传入布局,绑定表达式为viewModel.item.amount,其中viewModel.item是LiveData<MyItem>类型:
- DataBinding原生支持LiveData的观察逻辑,只要你给Binding设置了正确的
LifecycleOwner,DataBinding会自动监听这个LiveData的变化,只要LiveData的值(也就是MyItem实例)发生更新,就会自动重新读取amount属性刷新UI,哪怕MyItem的属性通知逻辑有问题也能正常工作。
第二种绑定方式是直接传入mViewModel.getItem().getValue()的返回值,本质是把执行绑定代码那一刻LiveData存储的MyItem实例直接传给了Binding,会出现以下两种问题:
- 如果你更新
LiveData<MyItem>是通过setValue/postValue传入新的MyItem实例(这是MVVM开发的常规写法),此时Binding持有的还是旧的MyItem实例,后续新实例的任何变化都完全不会通知到Binding,自然不会刷新UI。 - 如果你是直接修改原有MyItem实例的
amount属性,也需要满足两个条件才会触发更新:- MyItem必须继承
BaseObservable(你提供的代码片段没有声明父类,这是很多开发者容易遗漏的点) notifyPropertyChanged传入的BR常量必须和@Bindable注解标记的属性名完全匹配,你代码中写的BR.aMOUNT大小写和属性名amount不符,会导致属性变更通知无法正确触发。第一种场景能正常工作是因为LiveData更新时会强制重新读取整个表达式的值,绕过了单属性通知的逻辑。
- MyItem必须继承
内容的提问来源于stack exchange,提问作者mantc_sdr
相关产品推荐
相关产品推荐

