我正在使用Room数据库使用PagedList体系结构组件,但无法将结果返回给watch方法。
这是我的道:
@Dao
interface WorkPackageStorageDao {
@Query("SELECT * from workpackages where id = :id")
fun getById(id: String): Workpackage
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(workpackage: Workpackage)
@Query("Select * from workpackages WHERE id LIKE '%' || :searchString || '%' order by :orderBy")
fun searchWorkpackages(searchString : String, orderBy : String) : DataSource.Factory<Int, Workpackage>
@Query("SELECT * FROM workpackages")
fun searchWorkPackgesTest() : List<Workpackage>
@Query("Select * from workpackages WHERE id LIKE '%' || :searchString || '%' order by :orderBy")
fun searchWorkPackgesTestQuery(searchString : String, orderBy : String) : List<Workpackage>
@Query("DELETE from workpackages")
fun deleteAll()
}
我的存储库:
fun getAllWorkPackagesTestQuery() : List<Workpackage> {
return workpackagesDao.searchWorkPackgesTestQuery("",SortedBy.WorkPackageNumber.type)
}
fun getAllWorkPackages() : DataSource.Factory<Int, Workpackage> {
return getSortedAndSearchedWorkPackages("",
SortedBy.WorkPackageNumber
)
}
fun getSortedAndSearchedWorkPackages(searchString : String, sortBy: SortedBy) : DataSource.Factory<Int, Workpackage> {
return workpackagesDao.searchWorkpackages(searchString,sortBy.type)
}
这是我的视图模型中的方法:
suspend fun fetchWorkPackagesInitial(
workWeek: Configurations.AppWeek,
pagingLimit: Int
) {
coroutineScope {
withContext(Dispatchers.IO) {
val factory: DataSource.Factory<Int, Workpackage> =
workPackageRepository.getAllWorkPackages()
val pagedListBuilder =
LivePagedListBuilder<Int, Workpackage>(factory, pagingLimit)
workPackagesList = pagedListBuilder.build()
val list = workPackageRepository.getAllWorkPackagesTestQuery() //27 Items returned, query is fine.
}
}
}
这是我的片段:
mainViewModel.week.observe(this, Observer {
it ?: return@Observer
launch { workPackagesViewModel.fetchWorkPackagesInitial(it, PAGING_LIMIT) }
})
//Observe never called.
workPackagesViewModel.workPackagesList?.observe(this, Observer { wpList ->
wpList ?: return@Observer
adapter = WorkPackagesRecyclerAdapter(this)
adapter.submitList(wpList)
binding.workPackagesRecyclerView.adapter = adapter
adapter.notifyDataSetChanged()
})
作为对我的查询的测试,我实现了:
val list = workPackageRepository.getAllWorkPackagesTestQuery()
它返回27个项目,所以查询很好。我设置的Dao错误,LivePagedListBuilder错误吗?为什么不叫观察?
答案 0 :(得分:1)
您没有收到商品,因为它是PagedList
。您需要触发加载才能获取页面。
这就是为什么通过PagedListAdapter
将PagedList赋予submitList
会最终加载数据的原因。
使用adapter.notifyDataSetChanged()
时,您也不需要手动调用PagedListAdapter
,因为DiffUtil会在内部进行处理。
但是,您绝对应该在UI线程(DataSource.Factory
)上检索LivePagedListBuilder
和PagedList
以及Dispatcher.MAIN
,因为线程是由分页库的内部集成房间。观察(并在已卸载的元素上调用getItem(
)将触发加载,并且DataSource
可以立即执行加载。
使用分页的方法如下:
class MyViewModel(
private val workPackageStorageDao: WorkPackageStorageDao
): ViewModel() {
private val searchQuery: MutableLiveData<String> = MutableLiveData("")
val workPackages: LiveData<PagedList<WorkPackage>> = Transformations.switchMap(searchQuery) { searchText ->
val factory = workPackageStorageDao.searchWorkPackages(searchText, SortedBy.WorkPackageNumber)
val pagedListBuilder = LivePagedListBuilder<Int, WorkPackage>(factory, pagingLimit)
pagedListBuilder.build()
}
}
然后片段:
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// ... setup RecyclerView, etc
viewModel = ViewModelProviders.of(this).get(MyViewModel::class.java, viewModelFactory)
viewModel.workPackages.observe(viewLifecycleOwner, Observer { pagedList ->
adapter.submitList(pagedList)
})
}
在适配器中:
class MyAdapter: PagedListAdapter<WorkPackage, MyAdapter.ViewHolder>(WorkPackage.ITEM_CALLBACK) {
override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
val workPackage = getItem(position)
if(workPackage != null) {
holder.bind(workPackage)
}
}
}
长话短说,这里不需要协程。使用分页库和LiveData,它将在正确的线程上加载。