Android 使用来自 MutableStateFlow<List<MyDataObject>>() 的数据对象字段的值更新 activity
Android update activity with value of data object field from MutableStateFlow<List<MyDataObject>>()
当我更改用于显示下载进度条的对象中的字段值时,我无法可靠地从 viewModel()
更新我的 activity/UI 图层。 activity 观察到对象在列表中的添加和删除正常,但没有更改进度字段。
数据Class
data class DownloadObject(
val id: String?,
var progress: Float,
)
视图模型
class MyViewModel () : ViewModel() {
private val _progressList = MutableStateFlow<List<DownloadObject>>(emptyList())
val progressList: StateFlow<List<DownloadObject>>
get() = _progressList
//add to list updates the activity
_progressList.value += DownloadObject
//remove from list updates the activity
_progessList.value -= DownloadObject
// Change progress field doesn't update the activity
_progressList.value.onEach{
if(it.id == id) {it.progress = progress}
}
}
Activity
val progressList by courseViewModel.progressList.collectAsState(emptyList()
...
LinearProgressIndicator(progress = progressList.find { it.id == id }?.progress)
我尝试过使用 mutableStateListOf()
和 MutableLiveData
,但遇到了许多相同的问题。我已经参加了 state codelabs 的 compose,但我真的不确定从这里开始做什么。非常感谢任何帮助,谢谢!
// Change progress field doesn't update the activity
_progressList.value.onEach{
if(it.id == id) {it.progress = progress}
}
这实际上不会在您的 progressList
StateFlow
中触发更新。
要做到这一点,你可能想使用这样的东西:
_progressList.value = progressList.value.map {
if(it.id == id) {
it.copy(progress = progress)
} else {
it
}
}
添加和删除您的列表实际上是在更新 UI,因为您正在使用“+”和“-”运算符执行这些操作,这些运算符会在后台创建一个新列表。因此,如果您想更新列表的内容,然后重新组合,您要么必须做类似的事情,要么改变您的方法。
第一个选项,你可以
_progressList.value = progressList.value.onEach{ // Or something of equivalent sort, if Kotlin is smart enough
if(it.id == id) {it.progress = progress}
}
更好的方法是在使用 compose 时始终使用 MutableState
而不是 Flow
或其他方法。它是死的干净。
见
class MyViewModel () : ViewModel() {
val progressList = mutableStateListOf<DownloadObject>()
/* Treat it as a regular list object now*/
_progressList += DownloadObject
_progessList.value -= DownloadObject
// It hopefully will work now
_progressList.forEach{
if(it.id == id) {it.progress = progress}
}
}
Activity:-
val progressList by courseViewModel.progressList // That's it
...
LinearProgressIndicator(progress = progressList.find { it.id == id }?.progress)
看看它是否有效并告诉我
当我更改用于显示下载进度条的对象中的字段值时,我无法可靠地从 viewModel()
更新我的 activity/UI 图层。 activity 观察到对象在列表中的添加和删除正常,但没有更改进度字段。
数据Class
data class DownloadObject(
val id: String?,
var progress: Float,
)
视图模型
class MyViewModel () : ViewModel() {
private val _progressList = MutableStateFlow<List<DownloadObject>>(emptyList())
val progressList: StateFlow<List<DownloadObject>>
get() = _progressList
//add to list updates the activity
_progressList.value += DownloadObject
//remove from list updates the activity
_progessList.value -= DownloadObject
// Change progress field doesn't update the activity
_progressList.value.onEach{
if(it.id == id) {it.progress = progress}
}
}
Activity
val progressList by courseViewModel.progressList.collectAsState(emptyList()
...
LinearProgressIndicator(progress = progressList.find { it.id == id }?.progress)
我尝试过使用 mutableStateListOf()
和 MutableLiveData
,但遇到了许多相同的问题。我已经参加了 state codelabs 的 compose,但我真的不确定从这里开始做什么。非常感谢任何帮助,谢谢!
// Change progress field doesn't update the activity
_progressList.value.onEach{
if(it.id == id) {it.progress = progress}
}
这实际上不会在您的 progressList
StateFlow
中触发更新。
要做到这一点,你可能想使用这样的东西:
_progressList.value = progressList.value.map {
if(it.id == id) {
it.copy(progress = progress)
} else {
it
}
}
添加和删除您的列表实际上是在更新 UI,因为您正在使用“+”和“-”运算符执行这些操作,这些运算符会在后台创建一个新列表。因此,如果您想更新列表的内容,然后重新组合,您要么必须做类似的事情,要么改变您的方法。
第一个选项,你可以
_progressList.value = progressList.value.onEach{ // Or something of equivalent sort, if Kotlin is smart enough
if(it.id == id) {it.progress = progress}
}
更好的方法是在使用 compose 时始终使用 MutableState
而不是 Flow
或其他方法。它是死的干净。
见
class MyViewModel () : ViewModel() {
val progressList = mutableStateListOf<DownloadObject>()
/* Treat it as a regular list object now*/
_progressList += DownloadObject
_progessList.value -= DownloadObject
// It hopefully will work now
_progressList.forEach{
if(it.id == id) {it.progress = progress}
}
}
Activity:-
val progressList by courseViewModel.progressList // That's it
...
LinearProgressIndicator(progress = progressList.find { it.id == id }?.progress)
看看它是否有效并告诉我