Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Room Paging 3动态筛选的正确方法_Android_Android Room_Android Paging 3 - Fatal编程技术网

Android Room Paging 3动态筛选的正确方法

Android Room Paging 3动态筛选的正确方法,android,android-room,android-paging-3,Android,Android Room,Android Paging 3,我正在调查新的Android房间分页库 implementation "androidx.paging:paging-runtime-ktx:3.0.0-alpha09" 我的源数据库表大约有10000行,我按名称字段的第一个字符进行过滤,如下所示:- 刀 每次更改以字符开头的字符时,重复使用lifecycleScope.launch{…}是否正确 我应该是由StartWith的MutabableLiveData触发的map{}还是switchMap{}?这将不起作用

我正在调查新的Android房间分页库

   implementation "androidx.paging:paging-runtime-ktx:3.0.0-alpha09"
我的源数据库表大约有10000行,我按名称字段的第一个字符进行过滤,如下所示:-

每次更改以字符开头的字符时,重复使用
lifecycleScope.launch{…}
是否正确


我应该是由StartWith的
MutabableLiveData
触发的
map{}
还是
switchMap{}

这将不起作用,因为在
PagingData
无效之前,submitData不会返回。您可能会遇到竞争场景,其中启动了多个作业,
PagingDataAdapter
正试图从多个
PagingData
收集作业

更为“流”的方式是将获取调用转换为流,并将其与
流相结合,这将在每次查询更改时自动传播取消

还有几件事:

建议让分页为您进行过滤,因为这样可以避免每次搜索更改时都从数据库中重新获取,而且您还可以依靠分页来处理配置更改和恢复状态

您应该使用
viewLifecycleOwner
而不是直接使用
lifecycleScope
,因为您不希望在片段的视图被销毁后分页工作

e、 g

视图模型

fun fetch(startsWith: String): Flow<PagingData<CitationStyleDO>> {
    return repository.fetch(startsWith).cachedIn(viewModelScope)
}
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. 
queryFlow.flatMapLatest { query ->
    Pager(...) { dao.pagingSource(query) }
        .cachedIn(...)
}
碎片

override fun onStartsWithClicked(startsWith: String) {
    lifecycleScope.launch {
        viewModel.fetch(startsWith).collectLatest { adapter.submitData(it) }
    }
}
override fun onStartsWithClicked(startsWith: String) {
    viewModel.queryFlow = startsWith
}

override fun onViewCreated(...) {
     viewLifecycleOwner.lifecycleScope.launch {
viewModel.pagingDataFlow.collectLatest { adapter.submitData(it) }
}
注意:如果需要,您完全可以使用Room进行过滤,可能正确的方法是在queryFlow上使用
.flatMapLatest
,并返回一个新的
分页器
,然后将查询项传递给dao函数,该函数返回一个
分页源

视图模型

fun fetch(startsWith: String): Flow<PagingData<CitationStyleDO>> {
    return repository.fetch(startsWith).cachedIn(viewModelScope)
}
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. 
queryFlow.flatMapLatest { query ->
    Pager(...) { dao.pagingSource(query) }
        .cachedIn(...)
}

过滤和执行api调用怎么样?我猜您可以执行一个api调用来保存对DB的响应,该响应稍后仍会发送到PagingSource这里的api调用是什么意思?您的意思是远程获取更多项目吗?这些操作发生在分页中的不同层上,因此不会改变我的答案中示例中应用过滤器操作符的方式。