这是我尝试使用的MutableStateFlow值:
val songList: MutableStateFlow<MutableList<Song>> = MutableStateFlow(arrayListOf())
我需要观察上面MutableList上的变化(在添加、removeAt等方法之后(,但无法实现。我的猜测是,由于只有列表的元素而不是列表本身发生了变化,所以collect方法不会被触发。
如果可能的话,我如何使用StateFlow实现这一点?如果没有,正确的方法是什么?
注意,我需要arrayListOf((的初始值,所以LiveData可能对我来说不够
在您的视图模型中:
val songList: MutableStateFlow<MutableList<Song>> = MutableStateFlow(emptyList()) // modified
fun add(song: Song) {
songList.update {
songList.value.toMutableList().apply { this.add(song) }
}
}
可堆肥:
val songs = yourViewModel.songList.collectAsStateWithLifecycle()
-
有益的阅读:嵌套属性更改时通知LiveData观察员
-
问题是什么:
如果嵌套字段发生更改,StateFlow和LiveData将不会得到通知。 -
示例1:更新列表中的特定项目(而不是添加/删除(。
-
示例2:更新对象的specifc属性。
解决方案:
-
创建助手扩展函数:
fun <T> List<T>.mapButReplace(targetItem: T, newItem: T) = map { if (it == targetItem) { newItem } else { it } }
-
动作反应(例如:点击事件(:
val newStudent = student.copy(isSelected = !student.isSelected) viewModel.updateStudents(student, newStudent)
-
ViewModel
:中的句柄fun updateStudents(currentStudent: Student, newStudent: Student) { val newList = _students.value.mapButReplace(currentStudent, newStudent) _students.value = newList }
要更新Stateflow中的MutableList,您必须根据以下条件映射项目,我已经完成了这一点,并且它运行得很好。
_userList.value = _userList.value.map {
if (it?.userName == updatedUser.userName) updatedUser
else it
}
这里_userList是一个MutableStateFlow@Sam Sen的解释对我的变通解决方案有很大帮助。