Android Room Paging3 动态过滤的正确方法

标签 android android-room android-paging-3

我正在研究新的 Android Room Paging 库

   implementation "androidx.paging:paging-runtime-ktx:3.0.0-alpha09"
我的源数据库表大约有 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>
存储库
fun fetch(startsWith: String): Flow<PagingData<CitationStyleDO>> {
    return Pager(
        PagingConfig(pageSize = 60, prefetchDistance = 30, enablePlaceholders = false, maxSize = 200)
    ) { database.citationStyleDao().fetch("$startsWith%") }.flow
}
View 模型
fun fetch(startsWith: String): Flow<PagingData<CitationStyleDO>> {
    return repository.fetch(startsWith).cachedIn(viewModelScope)
}
分段
override fun onStartsWithClicked(startsWith: String) {
    lifecycleScope.launch {
        viewModel.fetch(startsWith).collectLatest { adapter.submitData(it) }
    }
}
这是重复使用lifecycleScope.launch {...}的正确方法吗?每次更改 Starts With 字符时?
我应该是map{}switchMap{}MutabaleLiveData<String> 触发对于 StartwWith?

最佳答案

这是行不通的,因为 submitData 直到 PagingData 才返回。无效。您可能会遇到启动多个作业的竞争场景,其中 PagingDataAdapter正在尝试从多个 PagingData 收集.
更“流”的方式是将您的 fetch 调用转换为流并将其与您的 Flow<PagingData> 结合起来。 ,每次查询更改时都会自动传播取消。
其他几件事:
建议让 Paging 为您进行过滤,因为这样您可以避免每次搜索更改时从 DB 重新获取,并且您可以依靠 Paging 来处理配置更改和恢复状态。
您应该使用 viewLifecycleOwner而不是 lifecycleScope直接,因为您不希望在 fragment 的 View 被破坏后进行分页工作
例如。,
View 模型

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. 
分段
override fun onStartsWithClicked(startsWith: String) {
    viewModel.queryFlow = startsWith
}

override fun onViewCreated(...) {
     viewLifecycleOwner.lifecycleScope.launch {
viewModel.pagingDataFlow.collectLatest { adapter.submitData(it) }
}
注意:如果需要,您绝对可以使用 Room 进行过滤,可能是 .flatMapLatest 的正确方法在 queryFlow 上并返回一个新的 Pager每个尖齿,并将查询项传递给返回 PagingSource 的 dao 函数
View 模型
queryFlow.flatMapLatest { query ->
    Pager(...) { dao.pagingSource(query) }
        .cachedIn(...)
}

关于Android Room Paging3 动态过滤的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65106394/

相关文章:

android-recyclerview - 使用 LiveData、Room 和 DiffUtil 更新 RecyclerView 项目内的内部 View

Android Paging 3 : LoadType. APPEND 返回空远程键

android - 运行时异常-无法启动接收器

android - setOnItemClickListener 不工作

android - 是否可以通过蓝牙从 PC 向 Android 设备发送/接收语音

android - Room Android - 如何处理数据库版本升级

java - JAVA中特定时间以特定时间间隔运行的线程

android - 我如何构建我的 sqlite 查询以返回包含任何顺序的数据的行?

Android:Paging3 使用 cloud-firestore 创建 remotemediator