Android Fragment从共享ViewModel问题中收集SharedFlow

2023-12-30

目前我有一个ViewPager2片段(作为起始目的地),包含两个子片段:ActiveOrderFragment and CompletedOrderFragment,他们都有自己的ViewModel处理 api 调用(获取活动订单和已完成订单)。

当用户单击订单项时,它将导航到OrderEditorFragment,并且有一个“将项目设置为活动/已完成”按钮,单击该按钮将更新订单的状态(只需一个PUT请求),然后返回ViewPager2分段。

为了通知和刷新ActiveOrderFragment and CompletedOrderFragment,我创建了一个SharedFlow in OrderViewModel,这是一个共享的ViewModel:

class OrderViewModel(application: Application) : AndroidViewModel(application) {
    private val uiScope = viewModelScope
    private val _isOrderStatusChanged = MutableSharedFlow<Boolean>(replay = 1)          

    val isOrderStatusChanged: SharedFlow<Boolean>
        get() = _isOrderStatusChanged

    fun updateIsOrderStatusChanged() = _isOrderStatusChanged.emit(uiScope, true)            
}

然后我观察(收集)这个SharedFlow in onCreateView() of ActiveOrderFragment and CompletedOrderFragment:

viewLifecycleOwner.lifecycleScope.launch {
    viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.CREATED) {
        orderViewModel.isOrderStatusChanged.collect { 
            if (it) {
                Log.v("xxx", "refreshed!")
                viewModel.refreshActiveOrders()    //similar in CompletedOrderFragment
            }
        }
    }
}

问题来了:当我更改状态并返回页面时,它们都会收到通知并刷新。然而,现在我点击任意订单项进入编辑器页面,但什么也不做,然后返回,collect{}再次被调用,这不是预期的行为。如何预防呢?我想这与replay财产...


一些额外的信息:

  1. Why use viewLifecycleOwner代替lifecycleScope直接地。 https://stackoverflow.com/q/67422182/3466808
  2. 为什么需要replay = 1 for SharedFlow. https://stackoverflow.com/a/70262955/3466808

MutableSharedFlow<Boolean>(replay = 1) == MutableStateFlow<Boolean>(false)

重播是什么意思

MutableSharedFlow<Boolean>(replay = 0)什么也没抓到

MutableSharedFlow<Boolean>(replay = 1)捕获最新值

MutableSharedFlow<Boolean>(replay = 2)捕获最新的 2 个值

orderViewModel.isOrderStatusChanged.collect {
            Log.i("isOrderStatusChanged","$it")
        }

如果你用 diff 值设置 _isOrderStatusChanged 两次,你就会发现。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android Fragment从共享ViewModel问题中收集SharedFlow 的相关文章

随机推荐

  • 为什么 asp.net mvc 中的部分视图需要下划线

    只是为了区分对话框内使用的视图还是 foreach 循环 客户详细信息 中使用的视图 你不需要下划线 这只是一个约定 而MVC非常热衷于使用约定
  • Ruby on Rails 脚本控制台

    我没能跑 script console以前 它曾经抛出一个错误 因为我script console文件已包含 usr bin env ruby19 进行命中和试验后 我通过替换修复了此错误 usr bin env ruby19 with u
  • 数据声明 Haskell 中的类型约束

    我正在使用 Haskell 并尝试编写以下内容 data Scale s Scale s s 但是 我想做到这一点s必须是 Num 类型类的内容 例如 Int 或 Double 使用 Haskell 和 GHC 可以做到这一点吗 Yes L
  • 正则表达式匹配所有内容,直到最后一次出现 /

    使用正则表达式 Ant 中的 Replaceregexp 如何匹配 然后替换 从行开头到最后一次出现斜杠的所有内容 我需要从以下任何一个开始 replace this keep this replace this replace this
  • 是否存在通过有向图所有顶点的路径?

    给定G 一个有向图 是否存在一条经过G中所有顶点的路径 不一定是简单路径 我首先需要检查非循环图和强连通图中发生的情况 然后使用强连通分量的图找到一般图的解决方案 到目前为止 我已经发现 对于强连通图来说 总有一条路径 对于非循环图 如果有
  • 什么是 premain() 以及如何调用它?

    我从来没有听说过premain我觉得这样问有点愚蠢 但是这篇文章的答案 https stackoverflow com questions 9368764 calculate size of object in java建议运行它以获得In
  • 相对布局的对角溢出背景

    大家好 我想要布局的背景如下 现在我正在做的事情如下
  • Rails 邮件程序 mimepart 在消息正文中显示为文本

    我正在使用 ActionMailer 发送测试邮件 模板正在呈现 邮件正在正常投递 唯一的问题是 Google 在消息正文中显示 mimepart 和其他标头数据 这是邮件的代码 def testing mail to gt email p
  • 字符串排列的时间复杂度

    以下示例取自 破解编码面试 第 6 版 一书 根据本书 以下代码的时间复杂度为 O n 2 n 请参考示例12 第32 33页 public static void main String args new PermutationsTest
  • 学习Python:根据条件更改列表中的值

    抱歉问了这个非常基本的问题 但这实际上是一个由两部分组成的问题 给定一个列表 我需要替换 的值带有 i 和带有整数 10 的 x 列表并不总是具有相同数量的元素 因此我需要一个允许我执行此操作的循环 a 1 7 8 5 x 如何获取值等于
  • 在选项卡中加载不同的活动

    我花了相当长的时间搜索 stackoverflow 和 google 但找不到正确向我解释如何在我的应用程序中实现选项卡的指南 我知道不应该使用 TabActivity 我还阅读了有关不要使用 TabHost 的建议 至少是这样理解的 我的
  • 当我的文本显示为问号时,这意味着什么?

    我正在尝试使用 例如 Windows GDI 在程序中显示一些文本 并且某些 unicode 字符显示为问号 怎么了 也可以看看 当我的文本显示为方框时 这意味着什么 https stackoverflow com questions 21
  • 可变参数模板示例

    考虑下面的代码 我不明白为什么必须定义 print 的空函数 include
  • Windows 转储文件格式

    我一直致力于创建更好的工具来处理我的组织中的转储 对于核心转储 linux 这很简单 因为它们是具有已知格式的 ELF 文件 然而 我们有一些 Windows 系统 它们生成的转储似乎不是 ELF 我知道有 Windows 工具可以处理这些
  • 带有 MarkupExtension 的 IValueConverter

    最近我读到一篇关于IValueConverter它也继承自MarkupExtension 它是这样的 internal class BoolToVisibilityConverter MarkupExtension IValueConver
  • Android 日志记录 - 如何清除以获得更好的性能

    Android新手 刚刚看了http developer android com reference android util Log html http developer android com reference android ut
  • 如何打印随机数菱形?

    有人可以帮我完成这个数字钻石吗 我打印了钻石的右侧 但在打印左侧时遇到了问题 如果有人可以提供帮助 我将非常感激 我对我的代码做了一些更改 我现在需要我的代码在菱形中间打印一列而不是两列 public class NumericDiamon
  • while 循环在需要时未结束

    所以一些背景信息 我是编程新手 仍在学习 所以我为我犯的微不足道的错误道歉 我正在制作自己的基于文本的游戏只是为了进一步练习等 以下是 Dropbox 上所有内容的链接 以了解更多背景信息 https www dropbox com sh
  • Monad 变压器:IO 和状态

    这个问题与其他地方已经涵盖的问题很接近 但我还没有找到任何具体解决它的内容 至少不是以我能够理解的方式 我想以取决于各种随机选择的方式更新状态 由于我正在使用 RandomSource 类型类的实例 所有这些随机选择都存在于 IO mona
  • Android Fragment从共享ViewModel问题中收集SharedFlow

    目前我有一个ViewPager2片段 作为起始目的地 包含两个子片段 ActiveOrderFragment and CompletedOrderFragment 他们都有自己的ViewModel处理 api 调用 获取活动订单和已完成订单