Paging
刷新数据以及解析
从刷新讲起
流程
Paging的
确很好用,省了很多步骤,但跟以往简单的刷新不同的是,Paging
比较麻烦,不能直接清空Adapter
里面的数据了和直接请求第一页的数据。以前清除列表,再重新请求第一页数据就可以了。那么Paging
如何刷新呢?大致上也和以前用法一样,无外乎就是清除数据并加载新数据
清除Adapter里面的数据
submitList()
通过传入null
值,如下源码:
public void submitList(final PagedList<T> pagedList) {
...
// incrementing generation means any currently-running diffs are discarded when they finish
final int runGeneration = ++mMaxScheduledGeneration;
if (pagedList == null) {
int removedCount = getItemCount();
if (mPagedList != null) {
mPagedList.removeWeakCallback(mPagedListCallback);
mPagedList = null;
} else if (mSnapshot != null) {
mSnapshot = null;
}
// dispatch update callback after updating mPagedList/mSnapshot
mUpdateCallback.onRemoved(0, removedCount);
if (mListener != null) {
mListener.onCurrentListChanged(null);
}
return;
}
...
}
也就是在传入值为null的情况下,最终会执行
mUpdateCallback.onRemoved(0, removedCount);
ListUpdateCallback是一个接口,其实现类如下:
/**
* ListUpdateCallback that dispatches update events to the given adapter.
*
* @see DiffUtil.DiffResult#dispatchUpdatesTo(RecyclerView.Adapter)
*/
public final class AdapterListUpdateCallback implements ListUpdateCallback {
@NonNull
private final RecyclerView.Adapter mAdapter;
/**
* Creates an AdapterListUpdateCallback that will dispatch update events to the given adapter.
*
* @param adapter The Adapter to send updates to.
*/
public AdapterListUpdateCallback(@NonNull RecyclerView.Adapter adapter) {
mAdapter = adapter;
}
/** {@inheritDoc} */
@Override
public void onInserted(int position, int count) {
mAdapter.notifyItemRangeInserted(position, count);
}
/** {@inheritDoc} */
@Override
public void onRemoved(int position, int count) {
mAdapter.notifyItemRangeRemoved(position, count);
}
/** {@inheritDoc} */
@Override
public void onMoved(int fromPosition, int toPosition) {
mAdapter.notifyItemMoved(fromPosition, toPosition);
}
/** {@inheritDoc} */
@Override
public void onChanged(int position, int count, Object payload) {
mAdapter.notifyItemRangeChanged(position, count, payload);
}
}
也就是onRemoved(0, removedCount)
还是调用了RecyclerView.Adapter
的notifyItemRangeRemoved()
,因此,如果在submitList()
传入null
值,最终会让Adapter移除从位置0开始的getItemCount()
个数据,即删除全部数据
请求第一页的数据
那么还有一个问题,就是加载第一页数据。Paging并没有根据页数请求数据的方法。即使接口是有提供这个方法,那么只能看DataSource
的loadInitial()
是在什么情况下被调用的了
在本项目中,DataSource
继承自PageKeyedDataSource
,查看在该类中loadInitial()
被调用情况
@Override
final void dispatchLoadInitial(@Nullable Key key, int initialLoadSize, int pageSize,
boolean enablePlaceholders, @NonNull Executor mainThreadExecutor,
@NonNull PageResult.Receiver<Value> receiver) {
LoadInitialCallbackImpl<Key, Value> callback =
new LoadInitialCallbackImpl<>(this, enablePlaceholders, receiver);
loadInitial(new LoadInitialParams<Key>(initialLoadSize, enablePlaceholders), callback);
// If initialLoad's callback is not called within the body, we force any following calls
// to post to the UI thread. This constructor may be run on a background thread, but
// after constructor, mutation must happen on UI thread.
callback.mCallbackHelper.setPostExecutor(mainThreadExecutor)