返回
换个思路,RecyclerView 轻松实现数据预加载
Android
2023-09-28 10:09:35
在很多场景下,我们需要分页加载数据,比如新闻列表、微博列表等。为了让用户体验更好,我们需要在用户快滑动到底部时就开始加载下一页数据,这样当用户滑动到底部时就可以无缝衔接到下一页数据,不会出现卡顿或白屏的情况。这种无感知的加载方式就叫做预加载。
实现RecyclerView预加载有多种方案,有的比较复杂,有的很强大。而我接下来介绍的这一种,极简,易于理解,而且非常灵活,适合各种业务场景。
首先,你需要定义一个抽象类IDataLoader
,IDataLoader
抽象了所有网络请求的行为,并定义了几个抽象方法,比如loadData
、cancel
等。IDataLoader
的实现类就是你实际的网络请求类。
public abstract class IDataLoader<T> {
protected abstract void loadData(int page, LoadCallback<T> callback);
protected abstract void cancel();
public interface LoadCallback<T> {
void onSuccess(List<T> data, int page);
void onFailure(Throwable e);
}
}
定义完IDataLoader
之后,你可以定义一个RecyclerView.Adapter
,Adapter
中有一个DataLoader
的引用,用于加载数据。
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private IDataLoader<MyData> mDataLoader;
private List<MyData> mData = new ArrayList<>();
public MyAdapter(IDataLoader<MyData> dataLoader) {
this.mDataLoader = dataLoader;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// ...
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
// ...
}
@Override
public int getItemCount() {
return mData.size();
}
public void loadData(int page) {
mDataLoader.loadData(page, new IDataLoader.LoadCallback<MyData>() {
@Override
public void onSuccess(List<MyData> data, int page) {
if (page == 1) {
mData.clear();
}
mData.addAll(data);
notifyDataSetChanged();
}
@Override
public void onFailure(Throwable e) {
// ...
}
});
}
}
最后,你需要定义一个RecyclerView.OnScrollListener
,OnScrollListener
中监听滚动的事件,当用户快滑动到底部时,就调用Adapter
的loadData
方法加载下一页数据。
public class MyOnScrollListener extends RecyclerView.OnScrollListener {
private MyAdapter mAdapter;
public MyOnScrollListener(MyAdapter adapter) {
this.mAdapter = adapter;
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (!recyclerView.canScrollVertically(1)) {
mAdapter.loadData(mAdapter.getItemCount() / 10 + 1);
}
}
}
至此,RecyclerView的预加载功能就实现了。这种预加载方式非常简单,易于理解和使用,而且非常灵活,适合各种业务场景。
当然,你也可以使用其他更复杂、更强大的预加载方案,但对于大多数场景来说,这种简单方案已经足够了。