我正在尝试使用来自Paging 3库的PagingAdapter找到一种更新RecyclerView单个项的方法。我只找到了一种用PagingAdapter.refresh()方法的方式。但是这个方法强制从网络加载所有列表。有人知道如何在不从网络加载所有页面的情况下实现它吗?
我正在尝试使用来自Paging 3库的PagingAdapter找到一种更新RecyclerView单个项的方法。我只找到了一种用PagingAdapter.refresh()方法的方式。但是这个方法强制从网络加载所有列表。有人知道如何在不从网络加载所有页面的情况下实现它吗?
目前,更新后备数据集的唯一方法是使列表失效并重新加载。对于使用缓存层(在数据库中,如room,或内存中)的分层源,这通常是一个可以接受的便宜选择,尽管仍在进行支持更精细的更新的工作(请参见https://issuetracker.google.com/160232968)。
就分层源而言,您需要将网络调用移动到RemoteMediator
中,并在Pager
的构造函数中注册它,然后将网络获取缓存到数据库中,例如Room(它可以为您生成一个PagingSource
实现),或者自己编写一个内存中的实现。
示例:
fun markItemAsRead(position: Int) {
snapshot()[position].read = true
notifyItemChanged(position)
}
class ExampleViewModel : ViewModel() {
private val _localDataList = MutableStateFlow(listOf<MyData>())
// Observe the Paging 3 Flow and combine it with the local Flow
val combinedDataList = paging3Flow.cachedIn(viewModelScope).combine(_localDataList) { paging, local ->
// Find and update the desired item in the list
paging.map {
if (it.id == local.id) local
else it
}
}
// Method to update the item in the local Flow
fun updateItem(item: MyData) {
val updatedItem = getUpdatedItemFromServerUseCase()
val newList = _localDataList.value.filterNot { it.id == updatedItem.id } // remove old version if any.
_localDataList.value = newList + updatedItem
}
}
enum class UpdateType {
UPDATE, REMOVE
}
data class UpdateData(
val updateType: UpdateType,
val item: MyData
)
class ExampleViewModel : ViewModel() {
private val _localDataList = MutableStateFlow(listOf<UpdateData>())
// Observe the Paging 3 Flow and combine it with the local Flow
val combinedDataList = paging3Flow.combine(_localDataList.) { paging, local ->
// Find and update or remove the desired item in the list
paging.map {
local.find { localItem -> localItem.item.id == it.id }?.let { localItem ->
when (localItem.updateType) {
UpdateType.UPDATE -> localItem.item
UpdateType.REMOVE -> null
}
} ?: it
}.filter { it!=null }
}
// Method to remove the item from the local Flow
fun updateItem(item: MyData) {
removeItemFromServerUseCase()
val newList = _localDataList.value.filterNot { it.item.id == item.id } // remove old version if any.
_localDataList.value = newList + UpdateData(UpdateType.REMOVE, updatedItem)
}
}
update
和remove
操作非常容易实现,但是add
更难(使用了insertFooterItem
)。在https://sourcediving.com/crud-operations-with-the-new-android-paging-v3-5bf55110aa4d上可以看到一个很好的例子。 - CoolMind(adapterComment.snapshot().items as MutableList<Model>)[position].likeStatus = 0
adapterComment.notifyItemChanged(position)
RemoteMediator
和自定义的PagingSource
同时使用吗?我认为自定义的PagingSource
会观察内存存储中的更改,然后使其无效。当单个项目的更新任务异步发生并且用户滚动RecyclerView
到不再屏幕上的位置时,这仍然能正常工作吗? - masterwokPagingSource.getRefreshKey
重新加载。新一代通过 DiffUtil 动态插入,所以这应该是可以工作的。 - dlam