前言:

纵观多数App,下拉刷新和上拉加载更多是很常见的功能,但是谷歌官方只有一个SwipeRefreshLayout用来下拉刷新,上拉加载更多还要自己做。

本篇文章基于RecyclerView简单封装了这两个操作,下拉刷新支持LinearLayoutManager、GridLayoutManager和StaggeredGridLayoutManager;上拉加载更多只支持前两者。

概述:

关于此篇文章,你需要提前了解:
1.实际项目开发过程中,能使用到下拉刷新和上拉加载更多功能的往往都和网络请求有关,即,下拉刷新和上拉加载更多需要有后台服务器的支持。

2.不管是下拉刷新还是上拉加载更多,本质上都是通过监听事件的触发而已。

3.如果是单纯的只是使用下拉刷新(不使用上拉加载更多),我们完全可以在每次触发下拉刷新操作时,直接将从后台服务器上请求下来的数据全部通过RecyclerView+Adapter进行展示即可,无须分页,也无须规定当前页展示多少条数据。

     //伪代码.....mListData.clear();mListData.addAll(value.getResults());adapter.notifyDataSetChanged();.........

但是如果项目中同时集成下拉刷新和上拉加载更多的话,则不管是下拉刷新还是上拉加载更过的接口中必然要涉及一下两个重要的参数:

parm 1:每页请求的数据 
parm 2:当前页数

原因很简:如果不设置这两个参数的话,在进行下来刷新时完全可以将所有的数据一起展示,上拉时也就不会触发什么加载更多的操作了。

说在前面:

之前想研究下拉刷新和上拉加载更多的示例代码。从网上找了好多,关于上拉加载更多的逻辑存在各种各样bug,简单有下面几类:

1.简单的模拟,没有后台服务器支持,逻辑走不通。
2.在上拉加载更多的最后的一个item的处理上存在逻辑混乱。虽然尝试做了更改,仍然不能使其正常运行。
3.对数据请求失败的处理不完善。
4.不支持GridLayoutManager对应的多行多列的实现。

好在老天有眼,终于找到一个比较完善的示Demo,如下:
手把手教你实现RecyclerView的下拉刷新和上拉加载更多

其中讲述了下拉刷新和上拉加载更多的使用步骤,以及需要重点关注的逻辑。因此本文就不再赘述其中上述博客已经存在的使用步骤,而是从项目结构的角度帮助大家更好理解和实现对上拉加载更多功能。

效果演示:

上图说话:

说在中间:

在分析项目结构之前呢,先把项目中用到相关知识点或者模式跟大家罗列一下,如果大家对列举的这些内容都已经了解或者已经掌握,则可以继续往下看,如果好多知识你都不曾接触过。那么你继续往下看的话会感到很迷茫,看不懂。(哈哈,有句话说的好,当你感到迷茫的时候,正是促使你学习的最佳时机,不要多想,行动起来吧。)

本项目用到的知识点罗列:
1.项目中用到的设计模式是标准的MVP模式(Model-View-Presenter)。
mvp速学通道:MVP模式使用示例详解

2.Rxjava+Retrofi实现网络请求
速学通道:
(1).Android Retrofit 2.0 的详细 使用攻略(含实例讲解)
(2).彻底搞清楚 RxJava 是什么东西
(3).分分钟使用Retrofit+Rxjava实现网络请求

3.ButterKnife.
ButterKnife是一个专注于Android系统View的注入框架,让你从烦人的findViewById中解脱出来。项目中使用的是版本比较老的ButterKnife,所以在获取控件实例时候,的注释字段可能会有些区别,eg.老本本使用的是InjectView,新版本使用的是bindView。这个比较简单。
速学通道:Android Butterknife使用方法总结

好了,上面列举的就是本项目中用到的且会影响到代码研读的知识点,提前先列出来。如果对上面的知识点有了基本的认知或者更深入的理解,才可以进入到下一步。

顺便说一下,上面列举的相关知识点,也是目前进行进行android项目开发时用到的最新最热的知识点。不要感觉这些东西很超前,相反,他们已经出来好几年了。霍霍,是不是意识到了点什么。。。。。

项目结构与分析:

分析:

adapter包:

1.AdapterWrapper.java


/*** 1. 显示或隐藏"滑动加载更多条目"* 2. 设置"滑动加载更多条目的状态"  提示加载或正在加载* 3. 末尾item由wapper添加, 其他item由原生adapter添加* 4. 隐藏"滑动加载更多条目"时, item数量减1* 5. 更新操作调用原生adapter的notifyDataSetChanged()* 6. 不支持StaggeredGridLayoutManager*/public class AdapterWrapper extends RecyclerView.Adapter {..........
...........

2.GankNewsAdapter.java

/*** "干货"/"福利"的adapter适配器*/
public class GankNewsAdapter extends RecyclerView.Adapter<GankNewsAdapter.MyViewHolder> {..........
...........

3.GankViewPagerAdapter.java

/*** 用于fragment中"android干货"和“福利”tab的切换的适配器*/
public class GankViewPagerAdapter extends FragmentPagerAdapter {..........
...........
bean包:

1.GankNewsBean.java

/*** 用于展示“android干货”的实体类对象*/
public class GankNewsBean implements Serializable {/*** 使用Gson解析json成对象时默认的是将json里对应字段的值解析到java对象里对应字段的属性里面*/@SerializedName("desc")private String mDesc;@SerializedName("images")private List<String> mImages;@SerializedName("publishedAt")private Date mPublishedAt;@SerializedName("url")private String mUrl;public String getDesc() {return mDesc;}public List<String> getImages() {return mImages;}public Date getPublishedAt() {return mPublishedAt;}public String getUrl() {return mUrl;}
}

2.GankResponseBean.java

/*** 封装的Retrofit返回的数据类* 使用Gson解析json成对象,默认的是将json里对应字段的值解析到java对象里对应字段的属性里面*/
public class GankResponseBean implements Serializable {@SerializedName("results")private List<GankNewsBean> mResults;public List<GankNewsBean> getResults() {return mResults;}}
contract包:

1.GankContract.java

/*** Presenter层接口---控制Model层的数据操作及调用View层的UI操作来完成“中间人”工作*/
public interface GankContract {/*** 用于view(Activity或者Fragment)中进行的ui操作*/interface View {void setPageState(boolean isLoading);void setListData(List<GankNewsBean> listData);void onRefreshComplete();void onLoadMoreComplete();void onInitLoadFailed();}/*** Presenter是连接model和view的纽带,因此其要提供获取model的接口*/interface Presenter {void onViewCreate();void onRefresh();void onLoadMore();}
}

2.GankPresenter.java

/*** GankPresenter是连接view和model的纽带,此处职能:通过view的调用去初始化view的相关逻辑,* 同时调用mode的相关接口去获得数据,并将数据返回给presenter*/
public class GankPresenter implements GankContract.Presenter {.............
.............

3.GankURLService.java

/*** 使用Rxjava和Retrofit封装的数据请求接口*/
public interface GankURLService {String BASE_URL = "http://gank.io/api/";@GET("data/{category}/{pagecount}/{page}")Observable<GankResponseBean> requestData(@Path("category") String category,@Path("pagecount") int countPerPage,@Path("page") int page);
}

4.NullOnEmptyConverterFactory.java

/*** 上面两个接口从服务端获取了数据,通过GsonConverterFactory将服务端相应内容解析成对应的实体类。* 在接口正常响应时(有数据返回),并没有什么异常发生,但当接口请求的数据为空,我们的服务端人员并不是返回理论意义上的空,* null或者[](数据集合空),而是返回没有响应体body,只有响应头header,content-length为0的Response*/
public class NullOnEmptyConverterFactory extends Converter.Factory {@Overridepublic Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {final Converter<ResponseBody, ?> delegate = retrofit.nextResponseBodyConverter(this, type, annotations);return new Converter<ResponseBody, Object>() {@Overridepublic Object convert(ResponseBody body) throws IOException {if (body.contentLength() == 0) return null;return delegate.convert(body);}};}
}

好了,主程序代码就不贴出来了,大家通过上面的项目结构先对整体功能结构划分有个了解。然后大家结合本项目的原来出处::::

手把手教你实现RecyclerView的下拉刷新和上拉加载更多
去学习如何应用把。记住多查,多学,多问!

说在最后:

文章最后,我会贴出此项目的示例源码。我在原来示例的基础上,添加了更为详细的注释,同时也对原来示例源码中描述明显有误的地方做了修改。当然了,你也可以直接下载原来博文中的源码示例。重点是要好好分析。
源码中有些比较难理解的地方,可能一时半会理解不过来。没关系,一步步来:
1.先学会如何使用,做到稍加修改就能满足自己的项目需求。
2.在今后再次遇到下拉刷新和上拉加载更多的需求的时候,继续研究。相信随着研究的深入以及相关问题的不断解决。我们一定能完全消化,化为己用。

示例代码下载:

https://download.csdn.net/download/zhangqunshuai/10703613

好了,至此完结,同时感谢原示例代码作者,小伙伴如果有疑问请留言,愿我们相互探讨,共同进步。

史上最全的使用RecyclerView实现下拉刷新和上拉加载更多相关推荐

  1. recyclerview的数据刷新(下拉刷新和自动加载更多)以及添加提示语(例如:“数据已加载完毕”)

    下拉加载更多的核心是SwipeRefreshLayout搭配Recyclerview进行使用.布局为 <android.support.v4.widget.SwipeRefreshLayout ...

  2. android 官方上拉,手把手教你实现RecyclerView的下拉刷新和上拉加载更多

    纵观多数App,下拉刷新和上拉加载更多是很常见的功能,但是谷歌官方只有一个SwipeRefreshLayout用来下拉刷新,上拉加载更多还要自己做. 基于RecyclerView简单封装了这两个操作, ...

  3. 使用SwipeRefreshLayout和RecyclerView实现仿“简书”下拉刷新和上拉加载更多

    原文地址: http://blog.csdn.net/leoleohan/article/details/50989549/ 一.概述 我们公司目前开发的所有Android APP都是遵循iOS风格设 ...

  4. vant实现下拉刷新和上拉加载_微信小程序 - 实现下拉刷新、上拉加载

    在小程序开发中使用下拉刷新和上拉加载非常多,比如常用的展示型首页,而实现这个功能有两种形式,第一种是使用 scroll-view 组件,第二种是不使用 scroll-view 组件而让整个页面刷新,那 ...

  5. uniapp实现下拉刷新及上拉(分页)加载更多(app,H5,小程序均可使用)

    开门见山地说,在移动端开发中,80%的项目都会涉及到列表展示,而有了列表不可避免的需求就是列表的下拉刷新和上拉加载更多.本篇文章主要介绍在使用uniapp开发移动端的过程中,比较好用的一个下拉及上拉组 ...

  6. 史上最全的机器学习资料(下)

    机器学习(Machine Learning, ML)是一门多领域交叉学科,涉及概率论.统计学.逼近论.凸分析.算法复杂度理论等多门学科.专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能 ...

  7. 采用SwipeFreshLayout+Recyclerview实现下拉刷新和上拉加载更多以及CoordinatorLayout的引入

    之前都是采用PullToRefresh进行下拉刷新和下拉加载,现在采用谷歌自己的控件SwipeFreshLayout,配合Recyclerview来实现这一效果.使用SwipeRefreshLayou ...

  8. 微信小程序 onReachBottom 上拉滚动到底部加载更多问题

    onReachBottom 小程序官方有一个onReachBottom上滑到底部执行的函数,但是当使用时发现不起作用.查了写资料发现需要在json里面配置: 1,"enablePullDow ...

  9. Vue2.0史上最全入坑教程(中)—— 脚手架代码详解

    2019独角兽企业重金招聘Python工程师标准>>> 书接上文我们说道,如何利用脚手架(vue-cli)构建一个vue项目,本回书我们一起来学习分析下代码. 回顾下创建后的项目目录 ...

  10. IM开发宝典:史上最全,微信各种功能参数和逻辑规则资料汇总

    1.引言 IM应用的初学者们,在补全了各种基础技术知识后(如果您仍不具备这些知识,建议马上阅读<新手入门一篇就够:从零开发移动端IM>),在动手编码实践时,很多时候纠结的并不是功能该如何实 ...

最新文章

  1. 前后端分离开发,RESTful 接口应该这样设计
  2. Solr 3.5:配置mmseg4j同义词(已经配置好中文分词)
  3. Apache Kafka-SpringBoot整合Kafka发送复杂对象
  4. bn层初始化参数_神经网络参数初始化方式
  5. 在微信浏览器中 location.reload() 不刷新解决方案(直接调用方法)
  6. 这个回答让我错失offer!offer拿到手软
  7. Java排序算法之直接选择排序
  8. 各机器学习平台视频建模功能汇总
  9. 跨平台移动应用开发框架AppCan2.0开发经验分享
  10. MFC字符串操作(二)CString.Format的用法
  11. PHP声音鉴定源码 微信趣味声音测试吸粉H5源码
  12. 独门秘籍 针式打印机换针小窍门
  13. 遇到“此网站的安全证书有问题”怎么办
  14. 奥特曼小分队之四(Work Breakdown Structure)
  15. 如何清理微信文件夹占用的巨大空间
  16. word 编辑过程中变为只读_WPS?教程 | WPS?云办公如何多人协同编辑
  17. python中幂运算_python里幂运算
  18. xset 关闭屏幕保护-关闭节电模式
  19. 淘宝社会工程学攻击手段
  20. 车间作业排序 java,9.4 派工单与作业排序

热门文章

  1. 建立数据库模型:从业务模型、概念模型到逻辑模型
  2. 计算机中显示器的分类,显示器怎么分类
  3. SONiC(3):手动运行docker ptf
  4. Performs recursive(递归) glob(全局) with given suffix and rootdir,使用os.walk(rootdir)和filename.endswith(s
  5. 考察一名UI设计师的能力素质模型(转)
  6. matlab产生窄带信号,窄带信号
  7. 微博、微信、qq、空间、等分享功能
  8. html 简繁转换 批量,[推荐]几行代码轻松搞定网页的【简繁转换】
  9. 剪辑视频,垂直翻转如何实现
  10. 【FPGA】Vivado综合停滞、死机(PID Not Specified)解决方法