收集 StateFlow 时 Api 没有响应不会更改 kotlin
Posted
技术标签:
【中文标题】收集 StateFlow 时 Api 没有响应不会更改 kotlin【英文标题】:No response from Api when collected StateFlow does not change kotlin 【发布时间】:2022-01-10 11:52:04 【问题描述】:在我的片段中,我有一个 RecyclerView,它显示了我在选项菜单中输入的查询的结果。它是我从中接收电视节目列表的 API。
查询需要长度至少为 3 的字符串。当它为 1 或 2 时,适配器被清除。
override fun onQueryTextChange(newText: String?): Boolean
if (newText != null && newText.length > 2)
if (!newText.isNullOrBlank() && newText.length > 2)
viewModel.searchMovies(newText)
else
adapter.setMoviesList(emptyList())
return true
但是,我在输入 e.g. 后遇到了问题。 “猫”两次。我收到了一份有猫的节目清单。从选项菜单中删除查询并再次对其进行录音后,适配器为空。并且没有相同的搜索。对我来说 -> 因为流量值没有改变。
在 ViewModel 我有:
private val _moviesStateFlow = MutableStateFlow<List<TvMazeShowResponse>>(emptyList())
val moviesStateFlow = _moviesStateFlow as StateFlow<List<TvMazeShowResponse>>
fun searchMovies(query: String)
viewModelScope.launch
val response = api.getApiResponse(query)
_moviesStateFlow.emit(response)
还有我在片段中收集的这个 StateFlow。
lifecycleScope.launch
viewModel.moviesStateFlow.collect
adapter.setMoviesList(it)
为了解决这个问题,我在 VM 中添加了另一个函数
fun clearFlow()
viewModelScope.launch
_moviesStateFlow.emit(emptyList())
现在在 onQueryTextChange
的片段中我添加了 else。
else
adapter.setMoviesList(emptyList())
viewModel.clearFlow()
现在它可以按预期工作了。但是有没有更好的方法来实现这一点?
【问题讨论】:
【参考方案1】:为减少您的代码复杂度,请避免在您的 UI 类(片段/活动/适配器)中执行逻辑,并让您的 ViewModel 提供单一的事实来源。
override fun onQueryTextChange(newText: String?): Boolean
viewModel.searchMovies(newText.orEmpty())
return true
// In ViewModel
fun searchMovies(query: String)
val trimmedQuery = query.trim()
viewModelScope.launch
val response = if (trimmedQuery.length <= 2) emptyList() else api.getApiResponse(trimmedQuery)
_moviesStateFlow.emit(response)
为避免在用户快速输入时运行多个过时的查询,我建议在开始新的搜索时取消以前的搜索。
private val searchJob? = null
fun searchMovies(query: String)
val trimmedQuery = query.trim()
searchJob?.cancel()
searchJob = viewModelScope.launch
val response = if (trimmedQuery.length <= 2) emptyList() else api.getApiResponse(trimmedQuery)
_moviesStateFlow.emit(response)
【讨论】:
以上是关于收集 StateFlow 时 Api 没有响应不会更改 kotlin的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Spring Boot WebClient 收集分页 API 响应?
Kotlin Flow响应式编程,StateFlow和SharedFlow