ViewModel的MutableLiveData赋值后Data Binding显示null如何解决
问题原因
- 核心问题:默认情况下,
by viewModels()生成的ViewModel实例作用域和当前所属Activity绑定,你在两个不同的Activity中各初始化了一次LockDetailsModel,拿到的是两个完全独立的实例。你在LockActivity中给name赋值的操作只作用于该页面对应的ViewModel实例,第二个展示页面拿到的是全新的未赋值的实例,所以name的值为null。 - 其他可能排查点:若已确保ViewModel是同一个实例仍出现null,可检查布局文件中是否正确声明了绑定变量、绑定表达式是否书写正确,比如是否漏写了
@{lockDetails.name}。
解决方案
根据你的业务场景选择对应的方案即可:
场景1:仅需要传递单次数值,无需跨页面同步更新
直接通过Intent携带参数传递即可,无需共享ViewModel:
- 在LockActivity跳转时添加参数:
val intent = Intent(this, ConnectLockActivity::class.java) intent.putExtra("unit_name", unitName.toString()) startActivity(intent)
- 在展示页面的Activity中拿到参数后赋值给ViewModel:
val viewModel: LockDetailsModel by viewModels() val unitName = intent.getStringExtra("unit_name").orEmpty() viewModel.setName(unitName) // 原有绑定逻辑保持不变 val binding: ActivityConnectLockBinding = DataBindingUtil.setContentView(this, R.layout.activity_connect_lock) binding.lockDetails = viewModel binding.lifecycleOwner = this
场景2:需要跨页面同步更新name数据
建议调整为单Activity多Fragment的架构,两个页面均作为Fragment存在,此时通过by activityViewModels()获取的ViewModel会绑定到宿主Activity的作用域,两个Fragment拿到的是同一个实例,可以正常共享数据:
// Fragment中获取共享ViewModel的方式 val viewModel: LockDetailsModel by activityViewModels()
如果必须保留双Activity的架构,可以自定义作用域到Application的ViewModelStore,实现全局共享ViewModel(不推荐,会导致ViewModel的生命周期过长,内存泄漏风险升高)。
额外优化建议
可以给LiveData设置初始默认值,避免空值展示:
// 修改ViewModel中的name声明,设置初始空字符串 var name = MutableLiveData<String>("")
内容的提问来源于stack exchange,提问作者mengmeng
相关产品推荐
相关产品推荐

