使用Data Binding展示StateFlow值时修改value后UI未更新问题求助
问题核心原因
- 布局中Data Binding的表达式错误,直接取了StateFlow的
value静态值,没有触发流观察 - 给StateFlow赋值时用了同一个实例,StateFlow基于
equals判断值是否变化,相同实例不会触发更新通知
解决步骤
1. 修正XML绑定表达式
你当前布局中直接读取了selectedAlarm.value的静态值,DataBinding不会监听后续StateFlow的变化。只要去掉.value即可,因为你已经给Binding设置了lifecycleOwner,DataBinding会自动收集StateFlow的发射值:
<!-- 修改前 --> android:text="@{Utility.INSTANCE.timeToString(alarmsViewModel.selectedAlarm.value.time)}" <!-- 修改后 --> android:text="@{Utility.INSTANCE.timeToString(alarmsViewModel.selectedAlarm.time)}"
2. 给StateFlow赋值时使用新实例
你的Alarm类目前是普通类,默认equals方法比对的是实例引用,你修改同一个实例的time属性再赋值回StateFlow,StateFlow会认为值没有变化,不会下发更新。
首先把Alarm改成data class,这样equals会比对所有属性值:
@Parcelize @Entity data class Alarm( @PrimaryKey(autoGenerate = true) val id: Int = 0, var time: Calendar = Calendar.getInstance(), ... ) : Parcelable
然后修改时间选择后的赋值逻辑,创建新的Alarm实例再赋值给StateFlow:
picker.addOnPositiveButtonClickListener { // 创建新的Calendar实例,不要修改原有实例的属性 val newTime = Calendar.getInstance().apply { set(Calendar.HOUR_OF_DAY, picker.hour) set(Calendar.MINUTE, picker.minute) } // 复制原有Alarm实例,替换time属性生成新实例 val newAlarm = alarmsViewModel.selectedAlarm.value.copy(time = newTime) alarmsViewModel.selectedAlarm.value = newAlarm }
3. 修正时间选择器初始化逻辑
你当前的代码只在setUpTimeField执行时读取了一次selectedAlarm的快照,后续如果selectedAlarm发生变化,弹窗初始化时还是会用旧值。把取值逻辑移到点击事件内部即可:
private fun setUpTimeField() { binding.llTimeField.setOnClickListener { // 每次点击都取最新的Alarm值 val currentAlarm = alarmsViewModel.selectedAlarm.value val picker = MaterialTimePicker.Builder() .setTimeFormat(TimeFormat.CLOCK_12H) .setTitleText("Set Time") .setHour(currentAlarm.time.get(Calendar.HOUR_OF_DAY)) .setMinute(currentAlarm.time.get(Calendar.MINUTE)) .build() picker.addOnPositiveButtonClickListener { val newTime = Calendar.getInstance().apply { set(Calendar.HOUR_OF_DAY, picker.hour) set(Calendar.MINUTE, picker.minute) } val newAlarm = currentAlarm.copy(time = newTime) alarmsViewModel.selectedAlarm.value = newAlarm } picker.show(childFragmentManager, "TIME_INPUT_DIALOG") } }
做完以上修改即可正常触发UI更新。
内容的提问来源于stack exchange,提问作者Al Ryan Acain
相关产品推荐
相关产品推荐

