Android 使用来自 MutableStateFlow<List<MyDataObject>>() 的数据对象字段的值更新活动
Posted
技术标签:
【中文标题】Android 使用来自 MutableStateFlow<List<MyDataObject>>() 的数据对象字段的值更新活动【英文标题】:Android update activity with value of data object field from MutableStateFlow<List<MyDataObject>>() 【发布时间】:2021-10-17 05:21:39 【问题描述】:当我更改用于显示下载进度条的对象中的字段值时,我无法可靠地从viewModel()
更新我的活动/UI 层。该活动可以很好地观察列表中对象的添加和删除,但不会更改进度字段。
数据类
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
活动
val progressList by courseViewModel.progressList.collectAsState(emptyList()
...
LinearProgressIndicator(progress = progressList.find it.id == id ?.progress)
我尝试过使用mutableStateListOf()
和MutableLiveData
,但遇到了许多相同的问题。我已经将两个州代码实验室都用于撰写,但我真的不知道从这里做什么。非常感谢任何帮助,谢谢!
【问题讨论】:
如果您希望您的问题得到解答,您需要让专家尽快获得具有可重现问题的工作样本。完美地,我应该将您的代码粘贴到我的示例项目中,并在我运行它时尽快看到问题。在您的情况下,我不知道您如何存储/更改id
以及为什么 find
可能不会以任何原因返回 null
【参考方案1】:
// 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
【讨论】:
【参考方案2】:在列表中添加和删除实际上是在更新 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
活动:-
val progressList by courseViewModel.progressList // That's it
...
LinearProgressIndicator(progress = progressList.find it.id == id ?.progress)
看看它是否有效并告诉我
【讨论】:
谢谢,虽然这确实更新了列表的内容,但它不会触发活动可观察到的状态更新。 哪个不会触发重组?第一种还是第二种方法? 这些方法都不会触发活动中的重组。这不是我向活动公开的变量类型的问题(mutableStateOf、mutableStateListOf、flow、MutableLiveData 等),因为我都试过了。我标记为正确的答案,映射然后复制条件,确实有效!以上是关于Android 使用来自 MutableStateFlow<List<MyDataObject>>() 的数据对象字段的值更新活动的主要内容,如果未能解决你的问题,请参考以下文章
使用 servlet/jsp 检查 HTTP 请求是不是来自 Android 手机
在 Android 上使用来自 libGDX 的 SQLite