观察未使用 LiveData<PagedList> 调用
Observe not called with LiveData<PagedList>
我正在通过 Room 数据库使用 PagedList 体系结构组件,但无法将结果返回到观察方法。
Here is my Dao:
@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()
}
My repository:
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)
}
Here is the method in my view model:
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.
}
}
}
Here is my fragment:
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()
其中returns27条,查询正常。我是否设置了 Dao 错误,LivePagedListBuilder 错误?为什么不调用 observe?
您没有收到物品,因为它是 PagedList
。需要触发加载才能获取页面
这就是为什么通过 submitList
将 PagedList 提供给 PagedListAdapter
最终会加载数据。
当您使用 PagedListAdapter
时,您也不需要手动调用 adapter.notifyDataSetChanged()
,因为 DiffUtil 会在内部处理它。
但是,您绝对应该在 UI 线程 (Dispatcher.MAIN
) 上检索 DataSource.Factory
和 LivePagedListBuilder
以及 PagedList
,因为线程由 Paging 库的 Room 集成在内部处理。观察(并在未加载的元素上调用 getItem(
)将触发加载,加载将由开箱即用的 DataSource
异步执行。
Paging的使用方法是这样的:
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)
}
}
}
长话短说,这里不需要协程。使用 Paging Library 和 LiveData,它将在正确的线程上加载。
我正在通过 Room 数据库使用 PagedList 体系结构组件,但无法将结果返回到观察方法。
Here is my Dao:
@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()
}
My repository:
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)
}
Here is the method in my view model:
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.
}
}
}
Here is my fragment:
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()
其中returns27条,查询正常。我是否设置了 Dao 错误,LivePagedListBuilder 错误?为什么不调用 observe?
您没有收到物品,因为它是 PagedList
。需要触发加载才能获取页面
这就是为什么通过 submitList
将 PagedList 提供给 PagedListAdapter
最终会加载数据。
当您使用 PagedListAdapter
时,您也不需要手动调用 adapter.notifyDataSetChanged()
,因为 DiffUtil 会在内部处理它。
但是,您绝对应该在 UI 线程 (Dispatcher.MAIN
) 上检索 DataSource.Factory
和 LivePagedListBuilder
以及 PagedList
,因为线程由 Paging 库的 Room 集成在内部处理。观察(并在未加载的元素上调用 getItem(
)将触发加载,加载将由开箱即用的 DataSource
异步执行。
Paging的使用方法是这样的:
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)
}
}
}
长话短说,这里不需要协程。使用 Paging Library 和 LiveData,它将在正确的线程上加载。