Android Data Binding:MutableSet类型MutableLiveData无法刷新UI
问题分析与解决方案
你猜的没错!问题就出在MutableSet本身——MutableLiveData只会在集合引用发生变化的时候才会触发UI更新,而你现在只是修改了集合内部的元素(add/remove),daysSet的引用还是原来那个HashSet,所以数据绑定根本没收到变更通知,自然不会刷新UI。
下面给你几个可行的解决办法,按推荐度排序:
1. 使用Data Binding原生的ObservableSet(最推荐)
Android Data Binding提供了专门支持变更通知的集合类型,ObservableSet就是其中之一。它内部会监听元素的添加/移除操作,自动通知数据绑定更新UI,完全不用依赖LiveData的引用变化。
修改ViewModel代码:
import androidx.databinding.ObservableSet // 直接用ObservableSet代替LiveData包裹的MutableSet val daysSet = ObservableSet<Days.Day>() fun evalDaySet(day: Days.Day): String { return if (!daysSet.contains(day)) { daysSet.add(day) "Add" } else { daysSet.remove(day) "Remove" } }
XML代码不用改:
android:textColor="@{viewModel.daysSet.contains(viewModel.days.mon) ? @color/selectedText : @color/black }"
这样每次调用evalDaySet修改集合时,UI会自动刷新文本颜色。
2. 手动触发LiveData的引用更新(简单直接但不够优雅)
如果你不想换集合类型,可以在修改完集合元素后,手动给LiveData设置一个新的引用(本质是把原来的集合重新post一遍),这样LiveData就会触发变更通知:
修改ViewModel的evalDaySet方法:
fun evalDaySet(day: Days.Day): String { val currentSet = daysSet.value ?: return "Error" val result = if (!currentSet.contains(day)) { currentSet.add(day) "Add" } else { currentSet.remove(day) "Remove" } // 关键:手动post一个新的引用(哪怕集合内容只是修改,引用换一下就会触发通知) daysSet.postValue(HashSet(currentSet)) return result }
注意这里要新建一个HashSet,不能直接post原来的currentSet——因为引用没变的话,LiveData还是不会触发更新。
3. 用Map实现需求(符合官方支持的集合类型)
官方文档提到的Map确实是受支持的,你可以用ObservableMap或者LiveData<MutableMap>来实现选中状态的管理,把Day枚举作为键,布尔值作为选中状态:
ViewModel代码(用ObservableMap):
import androidx.databinding.ObservableMap import androidx.databinding.ObservableHashMap val daysMap: ObservableMap<Days.Day, Boolean> = ObservableHashMap() // 初始化的时候可以给所有Day设置默认false init { Days.Day.values().forEach { daysMap[it] = false } } fun evalDaySet(day: Days.Day): String { val isSelected = daysMap[day] ?: false daysMap[day] = !isSelected return if (!isSelected) "Add" else "Remove" }
XML代码修改为:
android:textColor="@{viewModel.daysMap[viewModel.days.mon] ? @color/selectedText : @color/black }"
这种方式逻辑更清晰,直接用键值对管理选中状态,而且ObservableMap同样会自动通知UI更新。
内容的提问来源于stack exchange,提问作者Tae Soo Kim
相关产品推荐
相关产品推荐

