Paging Library是Google在2018年的io大会上发布的一个分页库,主要用于大量数据的分页加载,以减轻cpu负担,优化内存使用等。
其实之前一直可以自己实现这一功能,只不过这一次官方提供了标准化的api,对我这种只会Ctrl c + ctrl v的伪开发者来说无疑是个福音了。
之所以要用这个库,是因为当前的app中有一个我一直留到现在的bug,那就是新闻页面的评论加载不完全,只有第一页的最多30几个评论,后面的评论都被忽略了。
这是第一次使用kotlin和java混合开发,所以踩了不少坑。
Paging Library的使用其实也是挺简单的,主要是分成几步走:
一、改造原来的RecyclerView的Adaper
原先的Adapter直接派生自RecyclerView的内部抽象类Adapter,如果要应用于Paging Library,必须继承PagedListAdapter,从这个名字上就可以看出来,这个适配器是应用于“分成页加载的列表”,而这个PagedListAdapter又派生自RecyclerView.Adapter,中间多了一层继承关系,分页库在这里为我们封装好了一些必须的功能。
原来必须实现的getItemCount方法,在PagedListAdapter已经实现好了,改造的时候直接删除掉这个方法。
本来要在Activity中通过网络请求生成一个javaBean的列表,传进Adapter,Adapter才能根据这个列表进行model ->view的转换,而改造后的Adapter的数据直接从后面要提到的DataSource(数据源)中获取。
所以改造后,用于存放数据的list也可以直接删掉。
因为Paging Library一个核心点是根据需求进行动态加载,所以此时需要比较老的内容和新的内容是否重复,所以改造的时候需要增加一个DiffUtil.ItemCallback对象,用于确定新旧内容是否重复:
//用于确定是否重复
private static DiffUtil.ItemCallback<CommentBean> DIFF_CALLBACK = new DiffUtil.ItemCallback<CommentBean>() {
@Override
public boolean areItemsTheSame(@NonNull CommentBean oldItem, @NonNull CommentBean newItem) {
return oldItem.getCommentId() == newItem.getCommentId();
}
@Override
public boolean areContentsTheSame(@NonNull CommentBean oldItem, @NonNull CommentBean newItem) {
return oldItem.getCommentId() == newItem.getCommentId();
}
从这个匿名内部类对象的重写方法名字上可以看出,Paging Library确定是否重复是根据内容和整体来确定的,这里我只根据commentID来比较是否重复,所以两个方法都直接返回
oldItem.getCommentId() == newItem.getCommentId();
还有一个必须重写的getItemViewType方法,用于获取所要生成视图的类型:
@Override
public int getItemViewType(int position) {
return getItem(position).getViewType();
}
因为此时适配器的调用方从Activity变成了提供数据资源的DataSource对象,而且又删掉了保存JavaBean的列表,所以在改造后的适配器里面,直接用getItem(int position)方法就能获取所需要的数据,这个时候在onBindViewHolder方法里面,把list.get(position)替换为:
CommentBean comment = getItem(position);//从列表中拿出当前位置的数据
最后把适配器的构造函数改成: