【发布时间】:2018-06-30 07:54:51
【问题描述】:
我正在使用 分页库 使用 ItemKeyedDataSource 从网络加载数据。获取项目后用户可以对其进行编辑,此更新在 Memory 缓存中完成(不使用像 Room 这样的数据库)。
现在由于PagedList 本身无法更新(讨论here),我必须重新创建PagedList 并将其传递给PagedListAdapter。
更新本身没问题,但是在用新的PagedList 更新recyclerView 后,列表会跳转到列表的开头,破坏上一个 滚动位置。是否有在保持滚动位置的同时更新 PagedList(比如它如何与 Room 一起使用)?
DataSource 是这样实现的:
public class MentionKeyedDataSource extends ItemKeyedDataSource<Long, Mention> {
private Repository repository;
...
private List<Mention> cachedItems;
public MentionKeyedDataSource(Repository repository, ..., List<Mention> cachedItems){
super();
this.repository = repository;
this.teamId = teamId;
this.inboxId = inboxId;
this.filter = filter;
this.cachedItems = new ArrayList<>(cachedItems);
}
@Override
public void loadInitial(@NonNull LoadInitialParams<Long> params, final @NonNull ItemKeyedDataSource.LoadInitialCallback<Mention> callback) {
Observable.just(cachedItems)
.filter(() -> return cachedItems != null && !cachedItems.isEmpty())
.switchIfEmpty(repository.getItems(..., params.requestedLoadSize).map(...))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(response -> callback.onResult(response.data.list));
}
@Override
public void loadAfter(@NonNull LoadParams<Long> params, final @NonNull ItemKeyedDataSource.LoadCallback<Mention> callback) {
repository.getOlderItems(..., params.key, params.requestedLoadSize)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(response -> callback.onResult(response.data.list));
}
@Override
public void loadBefore(@NonNull LoadParams<Long> params, final @NonNull ItemKeyedDataSource.LoadCallback<Mention> callback) {
repository.getNewerItems(..., params.key, params.requestedLoadSize)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(response -> callback.onResult(response.data.list));
}
@NonNull
@Override
public Long getKey(@NonNull Mention item) {
return item.id;
}
}
PagedList 是这样创建的:
PagedList.Config config = new PagedList.Config.Builder()
.setPageSize(PAGE_SIZE)
.setInitialLoadSizeHint(preFetchedItems != null && !preFetchedItems.isEmpty()
? preFetchedItems.size()
: PAGE_SIZE * 2
).build();
pagedMentionsList = new PagedList.Builder<>(new MentionKeyedDataSource(mRepository, team.id, inbox.id, mCurrentFilter, preFetchedItems)
, config)
.setFetchExecutor(ApplicationThreadPool.getBackgroundThreadExecutor())
.setNotifyExecutor(ApplicationThreadPool.getUIThreadExecutor())
.build();
PagedListAdapter 是这样创建的:
public class ItemAdapter extends PagedListAdapter<Item, ItemAdapter.ItemHolder> { //Adapter from google guide, Nothing special here.. }
mAdapter = new ItemAdapter(new DiffUtil.ItemCallback<Mention>() {
@Override
public boolean areItemsTheSame(Item oldItem, Item newItem) {
return oldItem.id == newItem.id;
}
@Override
public boolean areContentsTheSame(Item oldItem, Item newItem) {
return oldItem.equals(newItem);
}
});
,并更新如下:
mAdapter.submitList(pagedList);
【问题讨论】:
-
您找到解决方法了吗?我确实注意到使用
.blockingFirst()而不是订阅,可以防止跳转 -
很遗憾,没有,从那以后我们使用自己的分页切换到 ListAdapter。
-
我遇到了类似的问题,回收站跳到了列表的中间。
-
@Blackbelt 谢谢!非常感谢,我整天都在寻找问题!文档中没有任何地方写过它!如果不是你的回答,我早就死了……谢谢!!!
-
我也面临同样的问题。有人找到解决方案了吗?
标签: android-recyclerview android-adapter android-architecture-components android-jetpack android-paging