如何在异步提交结果时观察 PagedList LiveData?
How to observe PagedList LiveData as it submit result asynchronously?
在下面的代码片段中,PagedList LiveData 只观察到一次。它成功地将下一页加载到 recyclerView。正如我们所知,它在内部使用异步调用将结果提交给适配器。
问题是如何为每个插入列表的新数据观察PagedList LiveData?
val callback = PostListAdapter.PagerCallback()
viewModel.posts.observe(viewLifecycleOwner, Observer<PagedList<PostData>> { pagedList ->
adapter.submitList(pagedList) //
adapter.updatePostList(pagedList) // I want to update this list on new data
pagedList.addWeakCallback(null, callback) // callback working fine.
}
我也尝试了 PagedList.Callback(),它工作正常但是没有观察到 LiveData。
class PagedCallback() : PagedList.Callback() {
override fun onChanged(position: Int, count: Int) {}
override fun onInserted(position: Int, count: Int) {
println("count: $count")
}
override fun onRemoved(position: Int, count: Int) {}
})
我找到了适合我的场景的解决方案并与大家分享。
我们无法在第一次调用后观察到 PagedList LiveData,因为它向适配器异步提交结果,这就是实时数据不会触发的原因。
解决方案:我添加了新的 LiveData 并在收到服务器响应后在 DataSource class 中更新它。
ViewModel
viewModel.posts.observe(viewLifecycleOwner, Observer { pagedList ->
adapter.submitList(pagedList)
})
// Added new LiveData to observer my list and pass it to detail screen
viewModel.postList.observe(viewLifecycleOwner, Observer {
adapter.updatePostList(it)
})
存储库
class MyRepository(private val api: ApiService) : {
val sourceFactory = MyDataSourceFactory(api) // create MyDataSource
val postList = Transformations.switchMap( // this is new live data to observe list
sourceFactory.sourceLiveData) { it.postList }
val data = LivePagedListBuilder(sourceFactory, PAGE_SIZE).build()
return Result(data, postList)
}
DataSourceFactory
class MyDataSourceFactory(private val api: ApiService) :
DataSource.Factory<String, PostData>() {
val sourceLiveData = MutableLiveData<MyDataSource>()
override fun create(): DataSource<String, PostData> {
val source = MyDataSource(api)
sourceLiveData.postValue(source)
return source
}
}
数据源
class MyDataSource(private val api: ApiService)
:PageKeyedDataSource<String, PostData>() {
val postList = MutableLiveData<List<PostData>>()
override fun loadInitial(
params: LoadInitialParams<String>,
callback: LoadInitialCallback<String, PostData>) {
//Api call here
val list = response.body()?.data
callback.onResult( // this line submit list to PagedList asynchronously
list,
response.body()?.data?.before,
response.body()?.data?.after)
postList.value = response.body().data // your LiveData to observe list
}
override fun loadAfter(
params: LoadParams<String>,
callback: LoadCallback<String, PostData>) {
//Api call here
val list = response.body()?.data?
callback.onResult( // this line submit list to PagedList asynchronously
list,
response.body()?.data?.before,
response.body()?.data?.after)
postList.value = response.body().data // your LiveData to observe list
}
在下面的代码片段中,PagedList LiveData 只观察到一次。它成功地将下一页加载到 recyclerView。正如我们所知,它在内部使用异步调用将结果提交给适配器。
问题是如何为每个插入列表的新数据观察PagedList LiveData?
val callback = PostListAdapter.PagerCallback()
viewModel.posts.observe(viewLifecycleOwner, Observer<PagedList<PostData>> { pagedList ->
adapter.submitList(pagedList) //
adapter.updatePostList(pagedList) // I want to update this list on new data
pagedList.addWeakCallback(null, callback) // callback working fine.
}
我也尝试了 PagedList.Callback(),它工作正常但是没有观察到 LiveData。
class PagedCallback() : PagedList.Callback() {
override fun onChanged(position: Int, count: Int) {}
override fun onInserted(position: Int, count: Int) {
println("count: $count")
}
override fun onRemoved(position: Int, count: Int) {}
})
我找到了适合我的场景的解决方案并与大家分享。
我们无法在第一次调用后观察到 PagedList LiveData,因为它向适配器异步提交结果,这就是实时数据不会触发的原因。
解决方案:我添加了新的 LiveData 并在收到服务器响应后在 DataSource class 中更新它。
ViewModel
viewModel.posts.observe(viewLifecycleOwner, Observer { pagedList ->
adapter.submitList(pagedList)
})
// Added new LiveData to observer my list and pass it to detail screen
viewModel.postList.observe(viewLifecycleOwner, Observer {
adapter.updatePostList(it)
})
存储库
class MyRepository(private val api: ApiService) : {
val sourceFactory = MyDataSourceFactory(api) // create MyDataSource
val postList = Transformations.switchMap( // this is new live data to observe list
sourceFactory.sourceLiveData) { it.postList }
val data = LivePagedListBuilder(sourceFactory, PAGE_SIZE).build()
return Result(data, postList)
}
DataSourceFactory
class MyDataSourceFactory(private val api: ApiService) :
DataSource.Factory<String, PostData>() {
val sourceLiveData = MutableLiveData<MyDataSource>()
override fun create(): DataSource<String, PostData> {
val source = MyDataSource(api)
sourceLiveData.postValue(source)
return source
}
}
数据源
class MyDataSource(private val api: ApiService)
:PageKeyedDataSource<String, PostData>() {
val postList = MutableLiveData<List<PostData>>()
override fun loadInitial(
params: LoadInitialParams<String>,
callback: LoadInitialCallback<String, PostData>) {
//Api call here
val list = response.body()?.data
callback.onResult( // this line submit list to PagedList asynchronously
list,
response.body()?.data?.before,
response.body()?.data?.after)
postList.value = response.body().data // your LiveData to observe list
}
override fun loadAfter(
params: LoadParams<String>,
callback: LoadCallback<String, PostData>) {
//Api call here
val list = response.body()?.data?
callback.onResult( // this line submit list to PagedList asynchronously
list,
response.body()?.data?.before,
response.body()?.data?.after)
postList.value = response.body().data // your LiveData to observe list
}