使用 StateFlow 和分页的 Android MVI 3

2024-03-16

我正在尝试使用状态流和分页 3 来实现 android MVI 架构,但是当我有一个包含分页数据的视图状态时,我感到很困惑。

问题是我将视图模型中的视图状态公开为状态流对象,但现在在该视图状态内我有另一个来自分页库的流对象。

状态流中可以有一个流吗?如果不是我应该做什么?

这是我的代码以供更多说明。

任务库

override fun list(
pageNumber: Int,
pageSize: Int,
groupId: Long?,
query: String
): Flow<PagingData<Task>> {
return Pager(
    config = PagingConfig(
        pageSize = Consts.PageSize,
        maxSize = 200,
        enablePlaceholders = false
    ),
    remoteMediator = TaskRemoteMediator(query, groupId, db, taskApi),
    pagingSourceFactory = {
        TaskDataSource(taskApi, groupId, query)
    }
).flow
}

任务视图模型

viewModelScope.launch {
try {
    _taskListViewState.emit(TaskListViewState.Loading)
    val tasks = taskRepo.list(1, Consts.PageSize, intent.groupId, "")
    _taskListViewState.emit(TaskListViewState.Data(tasks))
} catch (e: Exception) {
    _taskListViewState.emit(TaskListViewState.Error(R.string.unknown_error))
}
}

任务列表视图状态

sealed class TaskListViewState {
object Idle : TaskListViewState()
object Loading : TaskListViewState()
data class Data(val tasks: Flow<PagingData<Task>>) : TaskListViewState()
data class Error(val error: Int) : TaskListViewState()
}

任务列表片段

private fun observeViewState() {

lifecycleScope.launchWhenStarted {
    viewModel.taskListViewState.collect {
        render(it)
    }
}
}

private fun render(viewState: TaskListViewState) {
Log.d(TAG, "render: $viewState")
when (viewState) {
    is TaskListViewState.Loading -> showLoading()
    is TaskListViewState.Idle -> hildeLoading()
    is TaskListViewState.Error -> {
        hildeLoading()
        showMessage(viewState.error)
    }
    is TaskListViewState.Data -> {
        hildeLoading()
        lifecycleScope.launchWhenCreated {
            viewState.tasks.collectLatest {
                tasksAdapter.submitData(lifecycle, it)
            }

        }
    }
}
}

有点晚了,但您可以像下面这样修改类,并且不需要在 TaskListViewState 内进行流。

任务列表视图状态

sealed class TaskListViewState {
   object Idle : TaskListViewState()
   object Loading : TaskListViewState()
   data class Data(val tasks: PagingData<Task>) : TaskListViewState()
   data class Error(val error: Int) : TaskListViewState()
}

任务视图模型

viewModelScope.launch {
    try {
        _taskListViewState.emit(TaskListViewState.Loading)
        taskRepo.list(1, Consts.PageSize, intent.groupId, "")
          .cacheIn(viewModelScope)
          .collectLatest { pagingData ->
             _taskListViewState.emit(TaskListViewState.Data(pagingData))
          }
    } catch (e: Exception) {
       _taskListViewState.emit(TaskListViewState.Error(R.string.unknown_error))
    }
}

任务列表片段

private fun observeViewState() {

    lifecycleScope.launchWhenStarted {
        viewModel.taskListViewState.collect {
            render(it)
        }
    }
}

private fun render(viewState: TaskListViewState) {
    Log.d(TAG, "render: $viewState")
    when (viewState) {
        is TaskListViewState.Loading -> showLoading()
        is TaskListViewState.Idle -> hildeLoading()
        is TaskListViewState.Error -> {
            hildeLoading()
            showMessage(viewState.error)
        }
        is TaskListViewState.Data -> {
            hildeLoading()
            tasksAdapter.submitData(lifecycle, viewState.tasks)
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 StateFlow 和分页的 Android MVI 3 的相关文章

  • Android 中的短信编码

    我的问题是我想发送特定类别和特定编码的短信 0 类和 7 位编码 当检查 Android Telephony SmsManager 和 SmsMessage 时 您无能为力 SmsManager 提供两个功能 发送文本消息和发送数据消息 如
  • 在 Android 中获取联系方式需要花费大量时间?

    您好 目前正在做一个与联系人相关的项目 我正在从联系人中获取详细信息 电子邮件 电话号码和联系人姓名 效果很好 但问题是获取联系方式需要很长时间 超过 1000 个联系人 包括从社交网站同步的联系人 这样我就放了一个Asynchronous
  • onBackPressed 仅关闭 ProgressDialog

    我意识到我的异步任务有一个小问题 我意识到 当我按 Android 设备上的后退按钮来关闭进度对话框和异步任务时 只有我的进度对话框被关闭 而我的异步任务仍在执行 我真的不知道为什么会发生这种情况 所以我只是希望有人能让我回到正确的轨道并帮
  • 标记上存在语法错误,需要 AnnotationName - 查询错误

    我收到了令牌语法错误 AnnotationName 预期出现在以下行 query findInBackground new FindCallback
  • 删除SD卡上的文件夹

    I tried File delete 但它不起作用 如何删除SD卡上的目录 我正在开发 Android 2 1 在删除目录本身之前 您必须将所有目录清空 请参阅here http www rgagnon com javadetails j
  • cordova - 删除不必要的权限

    我需要在游戏中播放声音 因此我将 org apache cordova media 插件添加到我的应用程序中 现在platforms android AndroidManifest xml包含2个我不需要的条目
  • Android 上的嵌套滚动

    我们的活动中有一个主要的水平滚动视图 以及嵌套在其中的几个垂直滚动视图 这个想法是水平滚动 直到找到所需的垂直列表 然后上下滚动 理想情况下 一旦开始垂直滚动 我希望垂直滚动具有 锁定 现在会发生什么 如果您非常小心 您可以垂直滚动 但如果
  • 使用 Delphi 10.2.1 Tokyo 的模态 Android 对话框

    我有以下用于在 Android 上显示模式消息的 Delphi 代码 该代码在 10 1 Berlin 上运行良好 但在 Delphi 10 2 1 Tokyo 上停止运行 此过程现在会挂起 Android 应用程序 procedure c
  • 如何实现可运行队列

    我正在尝试实现一个可运行队列 在异步任务期间依次执行 意味着队列中的下一个将在另一个完成后执行 我编写了一个管理器来管理这些可运行对象和本身就是可运行对象的任务 然后 我获取异步任务中的第一个任务并运行它 希望它能够在队列中运行 但是它最终
  • 如何在谷歌地图上显示闪烁的图标

    我想在谷歌地图上显示用户的当前位置 每件事对我来说都运转良好 我只是使用标记在地图上显示当前位置 现在我想让该标记像 Android 手机上的原始谷歌地图应用程序一样闪烁 我想我必须使用动画来达到这个目的 但我不知道如何使用它 我正在互联网
  • 即时应用程序上的文本转语音崩溃

    我正在实现一个即时应用程序 该应用程序利用 Android 设备上提供的文本转语音功能 我已经设法得到了TextToSpeech按照 Android 开发博客文章中详细说明的说明 实例已初始化并可在非即时应用程序中正常工作Android 中
  • 为什么我的字体大小在 android webview 对象中看起来比在 android 浏览器中查看时大得多?

    我正在尝试制作一个小型 Android 应用程序 它除了在 webview 对象而不是浏览中显示网站之外什么也不做 到目前为止它加载了目标网页 但文本和图像大小都比查看页面时大得多在实际设备浏览器中 在浏览器中 页面看起来正确 但在我的应用
  • 应用程序启动器图标显示在活动的操作栏上

    在我的操作栏上显示应用程序图标 我不希望它出现在操作栏上 我修改了 androidmanifest xml 并删除了android icon从活动元素中 即使图标正在显示
  • 尝试在后台使用 AsyncTask 解析 JSON 时强制关闭

    我是 Android 开发新手 正在研究 json 数据 我设法让解析工作 我想显示一个 ProgressDialog 我读到我需要使用 AsyncTask 但由于某种原因 一旦我将相同的工作代码放入 doInBackground 中 即使
  • Android smoothScrollTo 不调用 onScrollStateChanged

    我在用smoothScrollBy 滚动到 a 中的特定位置ListView 我希望在以下情况时得到通知ListView完成滚动以将其与当前集成onScrollStateChanged 当用户用手指滚动时触发的事件 目前我正在使用Timer
  • startDrag 方法 已弃用且无法编译程序

    startDrag android content ClipData android view View DragShadowBuilder java lang Object int 已弃用 如何解决这个问题而又不失去对旧版本的兼容性 还有
  • API 24 AccessibilityService.dispatchGesture() 方法如何工作?

    通过 API 24 我们有了一种向设备发送手势的方法 但是目前还没有可靠的文档或示例 我正在尝试让它工作 但目前手势每次都会点击 onCancelled 回调 这是我调用该方法的代码 TargetApi 24 private void pr
  • Android - onLoadFinished 未调用

    我遇到了装载机的问题 我有一个活动 它显示从本地数据库检索的记录列表 当活动启动时 记录会通过 LoaderManager initLoader 方法自动加载 还可以通过 ActionBarSherlock 中的刷新按钮手动刷新列表 但是
  • Android 布局以 开头 [重复]

    这个问题在这里已经有答案了 我是 Android 应用程序开发的初学者 我的问题很简单 我似乎无法确定布局文件夹中的 xml 文件是否应以以下开头 当我制作一个入门项目时 它不存在 但我也在读一本书 上面说它应该在那里 正确的方法是什么 嗯
  • PinnedHeaderListView 滚动和标题问题

    背景 我正在尝试模仿 Lollipop 的联系人应用程序显示联系人首字母的固定标题的方式 正如我所写的here https stackoverflow com q 27621425 878126 问题 由于原始代码 发现here http

随机推荐

  • jQuery html() 和换行符

    我使用 jQuery 和 Rails 并有以下代码 related html 我在浏览器中遇到问题 只有当部分中没有换行符时 才会替换 lated 元素的内容 这没什么大不了的 我可以将所有内容放在一行上 但这使代码非常难以阅读 有没有办法
  • 使用重命名替换文件名

    我想通过替换从 开始的所有字符后跟八个大写字母来重命名文件名 并仅保留扩展名 4585 10 148 H2A119Ub GTCTGTCA S51 mcdf mdup ngsFlt fm 4585 10 148 H3K27me3 TCTTCA
  • 通过 chrome.runtime.sendMessage 发送带有函数的对象

    我正在开发一个 chrome 扩展 我想用 chrome runtime sendMessage 发送一个对象 带有一些函数 现在做这样的事情 chrome runtime sendMessage something Funny 工作得很好
  • wget 只下载一个 index.html 文件,而不是其他大约 500 个 html 文件

    使用 Wget 我通常只收到一个 index html 文件 我输入以下字符串 wget e robots 关闭 rhttp www korpora org kant aa03 http www korpora org kant aa03
  • 在 maven-plugin-testing-harness 中注入 DefaultRepositorySystem 时出错

    我正在尝试基于现有 2 0 插件创建一个新的 Maven 3 0 3 插件 并促进 aether 获取一些依赖项 我尝试创建一个简单的测试来使用 maven plugin testing harness 版本 2 0 1 加载 mojo 但
  • Chrome 扩展:无法使 chrome.desktopCapture.chooseDesktopMedia 捕获窗口音频

    我正在尝试使用chrome desktopCapture chooseDesktopMediaAPI 用于从扩展窗口捕获音频 我从 popup js 页面发送捕获请求 显现 background scripts background js
  • 哪里与有

    为什么需要放置您自己创建的列 例如select 1 as number after HAVING并不是WHERE在 MySQL 中 不这样做有什么缺点吗WHERE 1 写出整个定义而不是列名 其他关于这个问题的回答都没有说到重点 假设我们有
  • 如何告诉继承类不要调用其基类的无参数构造函数?

    我惊讶地发现我的基类的无参数构造函数在我每次调用时都会被调用any派生类中的构造函数 我以为就是这样 base 是为了 为了明确地如果需要的话 可以调用基本构造函数 当我实例化派生类时 如何防止调用基构造函数 using System na
  • 使用 PHP 在 Mongo DB 文档中添加数据

    我想插入数据Mongo database使用 PHP 脚本 在year明智的文件 使其看起来像这样 所有年份都在一份文件中 cars 2017 car Motorolla color blue 2016 car Toyota color g
  • 自动完成未按预期渲染材质 UI

    我的自动完成组件正在从 API 中提取书籍列表 我将它们呈现为自动完成组件中的选项 并将它们输出为页面底部的列表以进行调试 还从 API 输出 JSON 两个问题似乎是交织在一起的 首先 自动完成选项似乎并不全是渲染 最多有 10 个结果
  • FileNotFoundException(未找到 DLL)

    我在一台客户的机器上遇到了奇怪的错误 它抛出 FileNotFoundException 但该 DLL 肯定就在 Executable 文件夹中 为什么找不到它 请指教 由于您没有包含完整的异常详细信息 心理调试是 32 位与 64 位不匹
  • jQuery 验证文本区域最大长度错误

    我正在使用 jQuery validate v 1 6 0 来验证我的表单 我的数据库字段之一限制为 1000 个字符 我向相应的文本区域添加了验证 如下所示 在我的页面标题中 我添加 form validate validate 在我的页
  • 将 JSON ID 密钥插入 ng-click 指令,然后将其传递到另一个控制器

    应用程序的这一部分显示用户任务的最少信息 当他们单击 查看详细信息 按钮时 他们将进入一个页面 该页面包含有关基于 ID 的特定 CAR 的更多信息 这是一张图片来帮助解释我正在谈论的第一部分 这是我的角度代码 EDIT 添加了 ui ro
  • 如何获取大表的计数?

    样本表 id col1 col2 col3 col4 col5 modifiedTime 1 temp1 temp2 temp3 temp4 temp5 1554459626708 上表有5000万条记录 col1 col2 col3 co
  • 构建分页光标

    我的活动存储在图形数据库中 在某些情况下 多项活动会被分组并聚合为一项活动 处理后的活动源可能如下所示 Activity 1 Activity 2 Grouped Activity Activity 3 Activity 4 Activit
  • 如何在 Linux 上的 Firefox 中从聚焦单选输入中删除边框/轮廓

    I know that there are pretty much answers on similar questions on SO but none of them seems to work for me The problem i
  • 从 XML 数据写入 SQLite 数据库

    给出以下代码来导出数据库中的每个表 string strSql SELECT FROM tableName SqliteConnection sqlCon new SqliteConnection Data Source dbPath us
  • 以编程方式设置 Angular 4 复选框

    我见过类似的问题 但我仍然不明白 我有一个组件女巫获取项目列表Array lt id number name string gt 以及 已检查 项目的列表Array
  • 这个编码字符串表示什么?您是如何发现的?

    我正在尝试建立一个产品目录 但我不知道它在做什么 我想看看里面 有人能弄清楚如何打印源代码并告诉我怎么做吗 FZrHbutatkV pXpVF2wwJ1S4YBZzjp0HRjGIOfPrH0 LgGFL5OZac45h e efvf5RH
  • 使用 StateFlow 和分页的 Android MVI 3

    我正在尝试使用状态流和分页 3 来实现 android MVI 架构 但是当我有一个包含分页数据的视图状态时 我感到很困惑 问题是我将视图模型中的视图状态公开为状态流对象 但现在在该视图状态内我有另一个来自分页库的流对象 状态流中可以有一个