我在项目中使用Paging Architecture Components从网络中加载列表(尚未使用数据库)。我的DataSource
是PositionalDataSource
的子类,而我的PagedList.Config
看起来像这样:
PagedList.Config config = new PagedList.Config.Builder()
.setPageSize(10)
.setInitialLoadSizeHint(20)
.setPrefetchDistance(20)
.setEnablePlaceholders(true)
.build();
启用了占位符,并且我在PagedListAdapter
子类中处理了空的ViewHolders,以不同方式显示占位符项。当在列表末尾加载其他项目时,占位符可以很好地工作,但是我还想在加载前几项(之前之前)显示占位符项目(如常规加载指示器)。
是否可以使用分页库来执行此操作?我试图用1
而不是0
的位置来呼叫LoadInitialCallback.onResult()
,但这只会在第一个实际项目之前创建一个占位符项目,而该占位符项目永远不会消失。
答案 0 :(得分:2)
我知道这个问题还很老,但是我回答了,因为这是我结束对这个问题进行搜索的地方。在v3中,您可以将LoadStateAdapter添加到“页眉”和“页脚”中,以进行“预加载”和“附加”加载状态。初始加载将是刷新状态,该状态似乎不包括在内,但是我们可以简单地复制功能并将其扩展为包括刷新:
我只是用LoadStateHeaderAndFooter复制并添加了可用于刷新的第三个适配器
private fun PagingAdapter.withLoadStateAll(
header: LoadStateAdapter<*>,
footer: LoadStateAdapter<*>,
refresh: LoadStateAdapter<*>
): ConcatAdapter {
addLoadStateListener { loadStates ->
header.loadState = loadStates.prepend
footer.loadState = loadStates.append
refresh.loadState = loadStates.refresh
}
return ConcatAdapter(refresh,header, this, footer)
}
然后,您只需按照文档将其注册到Recycler,它就会在初始加载时显示。
recycler.adapter = adapter.withLoadStateAll(LoadAdapter(),LoadAdapter(),LoadAdapter())
如果您需要在初始加载期间显示多个项目,只需复制LoadStateAdapter并将项目数从1更改为n:
class InitialLoadAdapter(private val num : Int) : RecyclerView.Adapter<LoadViewHolder>() {
var loadState: LoadState = LoadState.NotLoading(endOfPaginationReached = false)
set(loadState) {
if (field != loadState) {
val oldItem = displayLoadStateAsItem(field)
val newItem = displayLoadStateAsItem(loadState)
if (oldItem && !newItem) {
notifyItemRangeRemoved(0,num)
} else if (newItem && !oldItem) {
notifyItemRangeInserted(0,num)
} else if (oldItem && newItem) {
notifyItemRangeChanged(0,num)
}
field = loadState
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LoadViewHolder {
return LoadViewHolder(parent)
}
override fun onBindViewHolder(holder: LoadViewHolder, position: Int) {}
override fun getItemViewType(position: Int): Int = getStateViewType(loadState)
override fun getItemCount(): Int = if (displayLoadStateAsItem(loadState)) num else 0
private fun getStateViewType(loadState: LoadState): Int = 0
private fun displayLoadStateAsItem(loadState: LoadState): Boolean {
return loadState is LoadState.Loading || loadState is LoadState.Error
}
}
答案 1 :(得分:0)
有一种方法可以让您传递数据集大小,我认为这正是您所缺少的。
public abstract static class LoadInitialCallback<Key, Value> {
/**
* Called to pass initial load state from a DataSource.
* <p>
* Call this method from your DataSource's {@code loadInitial} function to return data,
* and inform how many placeholders should be shown before and after. If counting is cheap
* to compute (for example, if a network load returns the information regardless), it's
* recommended to pass data back through this method.
* <p>
* It is always valid to pass a different amount of data than what is requested. Pass an
* empty list if there is no more data to load.
*
* @param data List of items loaded from the DataSource. If this is empty, the DataSource
* is treated as empty, and no further loads will occur.
* @param position Position of the item at the front of the list. If there are {@code N}
* items before the items in data that can be loaded from this DataSource,
* pass {@code N}.
* @param totalCount Total number of items that may be returned from this DataSource.
* Includes the number in the initial {@code data} parameter
* as well as any items that can be loaded in front or behind of
* {@code data}.
*/
public abstract void onResult(@NonNull List<Value> data, int position, int totalCount,
@Nullable Key previousPageKey, @Nullable Key nextPageKey);
我尝试过,但是我都看不到预览。
检查http://youtube.com/watch?v=BE5bsyGGLf4
希望这会有所帮助