Hec*_*tor 3 android android-room android-paging-3
我正在研究新的 Android Room Paging 库
implementation "androidx.paging:paging-runtime-ktx:3.0.0-alpha09"
Run Code Online (Sandbox Code Playgroud)
我的源数据库表大约有 10,000 行,我按名称字段的第一个字符进行过滤,如下所示:-
道
@Query("SELECT * from citation_style WHERE citation_style_name LIKE :startsWith ORDER BY citation_style_name ASC")
fun fetch(startsWith: String): PagingSource<Int, CitationStyleDO>
Run Code Online (Sandbox Code Playgroud)
存储库
fun fetch(startsWith: String): Flow<PagingData<CitationStyleDO>> {
return Pager(
PagingConfig(pageSize = 60, prefetchDistance = 30, enablePlaceholders = false, maxSize = 200)
) { database.citationStyleDao().fetch("$startsWith%") }.flow
}
Run Code Online (Sandbox Code Playgroud)
视图模型
fun fetch(startsWith: String): Flow<PagingData<CitationStyleDO>> {
return repository.fetch(startsWith).cachedIn(viewModelScope)
}
Run Code Online (Sandbox Code Playgroud)
分段
override fun onStartsWithClicked(startsWith: String) {
lifecycleScope.launch {
viewModel.fetch(startsWith).collectLatest { adapter.submitData(it) }
}
}
Run Code Online (Sandbox Code Playgroud)
这是lifecycleScope.launch {...}每次更改开始字符时重复使用的正确方法吗?
我应该是map{}还是switchMap{}由MutabaleLiveData<String>for StartwWith触发?
这是行不通的,因为 submitData 在PagingData失效之前不会返回。您可能会遇到竞争场景,其中启动了多个作业,PagingDataAdapter试图从多个PagingData.
更“流”的方法是将您的 fetch 调用转换为流并将其与您的 结合Flow<PagingData>,这将在每次查询更改时自动传播取消。
其他几件事:
建议让 Paging 为您进行过滤,这样您就可以避免每次搜索更改时从数据库重新获取,并且您还可以依靠 Paging 来处理配置更改和恢复状态。
您应该使用viewLifecycleOwner而不是lifecycleScope直接使用,因为您不希望在片段视图被销毁后进行分页
例如,
视图模型
val queryFlow = MutableStateFlow("init_query")
val pagingDataFlow = Pager(...) {
dao.pagingSource()
}.flow
// This multicasts, to prevent combine from refetching
.cachedIn(viewModelScope)
.combine(queryFlow) { pagingData, query ->
pagingData.filter { it.startsWith(query)
}
// Optionally call .cachedIn() here a second time to cache the filtered results.
Run Code Online (Sandbox Code Playgroud)
分段
override fun onStartsWithClicked(startsWith: String) {
viewModel.queryFlow = startsWith
}
override fun onViewCreated(...) {
viewLifecycleOwner.lifecycleScope.launch {
viewModel.pagingDataFlow.collectLatest { adapter.submitData(it) }
}
Run Code Online (Sandbox Code Playgroud)
注意:如果需要,您绝对可以使用 Room 进行过滤,这可能是查询流.flatMapLatest上的正确方法并返回一个新的Pager每个 tine,并将查询词传递给返回一个的 dao 函数PagingSource
视图模型
queryFlow.flatMapLatest { query ->
Pager(...) { dao.pagingSource(query) }
.cachedIn(...)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
603 次 |
| 最近记录: |