我在ViewModel中有两个StateFlow列表(本地和远程),它们被组合到单个uiState中,用于编写用户界面.

用户正在从远程来源提取值,这些值将保存到本地房间数据库中.我希望筛选来自远程数据源的值,以便只显示这些尚未保存到本地数据库中的值.

下面是我目前的解决方案,但它并不像我想的那样工作.

当我将实体保存到本地数据库时,它会立即显示在本地值列表中,但不会从远程列表中消失.我认为这是因为emoteFlow没有更改,所以它不会发出新值,也不会使用map.

当用户进行刷新接口操作时,emoteFlow将发出新值,MAP将过滤结果,结果为OK.但我需要这种"第二冲动"才能让它发挥作用.

房间数据库创建的本地数据源:

private val localFlow: StateFlow<List<LocalEntity>> =
        repository.local.getLocalEntity().stateIn(
            scope = viewModelScope,
            started = SharingStarted.WhileSubscribed(5_000L),
            initialValue = listOf()
        )

远程数据源根据用户请求(点击)使用 retrofit 手动填充.

private val remoteFlow: MutableStateFlow<List<remoteEntity>> =
        MutableStateFlow(listOf())

这两个列表流被合并到uiState中.我try 使用map来实现所需的过滤.

val uiState = combine(
        remoteFlow.map { remoteList ->
            remoteList.filter { remote -> localFlow.value.firstOrNull { remote.id == it.id} == null }
        }
            .stateIn(
                viewModelScope,
                started = SharingStarted.WhileSubscribed(5_000L),
                initialValue = listOf()
            ),
        localFlow
    ) { remote, local->
        JobListUiState(remote, local)
    }.stateIn(
        scope = viewModelScope,
        started = SharingStarted.WhileSubscribed(5_000L),
        initialValue = JobListUiState()
    )

实现这一目标的正确方法是什么?在将新项目添加到本地列表时,是否可以检测远程列表中的更改?

推荐答案

您可以在combine‘S transform内部执行筛选,本地数据源的更新将调用该筛选.

val uiState = combine(
    remoteFlow,
    localFlow,
) { remote, local ->
    val localIds = mutableSetOf<Int>()
    local.mapTo(localIds) { it.id }
    val remoteFiltered = remote.filter { !localIds.contains(it.id) }
    JobListUiState(remoteFiltered, local)
}.stateIn(
//----

Android相关问答推荐

了解数据加载在Kotlin中的工作原理

将Android Studio插件复制到离线网络

无法将非静态方法与Frida挂钩

在Android 14/SDK 34中使用RegisterReceiver的正确方式是什么?

react 本机生成失败,出现异常.错误:无法确定';<;宏/>;的类型

Android Jetpack Compose调用view-model函数仅一次

为什么我有多个Player实例?

Jetpack Compose:如何将文本放置在行的右侧?

为什么可以';我不能直接在RecyclerView.ViewHolder中访问视图ID吗?

可以';t将数据插入房间数据库

在c中更新MVVMCross中TextView的Alpha#

如何在这段代码android jetpack compose中实现全屏滚动

如何在ExecutorService中设置progressBar的进度?不想使用 AsyncTask,因为它已被弃用

如何只允许拖动 BottomSheetScaffold 中 BottomContent 的 SheetPeek 的一部分?

没有互联网连接时,Firebase Storage putFile() 永远不会完成

Android 自动分页如何与 media3 配合使用?

如何在 Dolphin 中启用 android studio new logcat | 2021.3.1 金丝雀 6?

如何在jetpack compose中创建水印文字效果

如何在 Jetpack Compose 中填充矢量图像的背景?

Xamarin 获取动态 ListView DataTemplate 中的按钮单击事件数据