使用 StateFlow 和分页的 Android MVI 3

Mut*_*san 18 android kotlin android-paging-3 kotlin-stateflow

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

\n

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

\n

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

\n

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

\n

任务库

\n
override fun list(\npageNumber: Int,\npageSize: Int,\ngroupId: Long?,\nquery: String\n): Flow<PagingData<Task>> {\nreturn Pager(\n    config = PagingConfig(\n        pageSize = Consts.PageSize,\n        maxSize = 200,\n        enablePlaceholders = false\n    ),\n    remoteMediator = TaskRemoteMediator(query, groupId, db, taskApi),\n    pagingSourceFactory = {\n        TaskDataSource(taskApi, groupId, query)\n    }\n).flow\n}\n
Run Code Online (Sandbox Code Playgroud)\n

任务视图模型

\n
viewModelScope.launch {\ntry {\n    _taskListViewState.emit(TaskListViewState.Loading)\n    val tasks = taskRepo.list(1, Consts.PageSize, intent.groupId, "")\n    _taskListViewState.emit(TaskListViewState.Data(tasks))\n} catch (e: Exception) {\n    _taskListViewState.emit(TaskListViewState.Error(R.string.unknown_error))\n}\n}\n
Run Code Online (Sandbox Code Playgroud)\n

任务列表视图状态

\n
sealed class TaskListViewState {\nobject Idle : TaskListViewState()\nobject Loading : TaskListViewState()\ndata class Data(val tasks: Flow<PagingData<Task>>) : TaskListViewState()\ndata class Error(val error: Int) : TaskListViewState()\n}\n
Run Code Online (Sandbox Code Playgroud)\n

任务列表片段

\n
private fun observeViewState() {\n\nlifecycleScope.launchWhenStarted {\n    viewModel.taskListViewState.collect {\n        render(it)\n    }\n}\n}\n\nprivate fun render(viewState: TaskListViewState) {\nLog.d(TAG, "render: $viewState")\nwhen (viewState) {\n    is TaskListViewState.Loading -> showLoading()\n    is TaskListViewState.Idle -> hildeLoading()\n    is TaskListViewState.Error -> {\n        hildeLoading()\n        showMessage(viewState.error)\n    }\n    is TaskListViewState.Data -> {\n        hildeLoading()\n        lifecycleScope.launchWhenCreated {\n            viewState.tasks.collectLatest {\n                tasksAdapter.submitData(lifecycle, it)\n            }\n\n        }\n    }\n}\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Bun*_*ana 2

有点晚了,但您可以像下面这样修改类,并且不需要在 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()
}
Run Code Online (Sandbox Code Playgroud)

任务视图模型

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))
    }
}
Run Code Online (Sandbox Code Playgroud)

任务列表片段

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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)