最近在做需求的时候,需要实现列表的上拉加载功能。在这里进行记录分享。

其实上拉加载功能只需要为RecyclerView的Item布局添加一个FooterView,然后通过判断是否滑动到最后一条Item来控制FooterView的显隐来做到一个上拉加载的功能。先看代码

class PaperListAdapter(private val context: Context, private var paperList: List<PaperListModel>, private val subjectId: Int) :RecyclerView.Adapter<RecyclerView.ViewHolder>() {companion object {private const val TAG = "PaperListAdapter"const val TYPE_ITEM = 1const val TYPE_FOOTER = 2}//加载状态,默认加载中var loadState = 1//正在加载val loading = 1//加载完成val loaded = 2//加载到底val loadedEnd = 3inner class ViewHolder(val binding: PaperItemBinding) : RecyclerView.ViewHolder(binding.root)inner class FooterViewHolder(val footerBinding: PaperItemFooterBinding) :RecyclerView.ViewHolder(footerBinding.root)override fun getItemViewType(position: Int): Int {return if (position + 1 == itemCount) {TYPE_FOOTER} else {TYPE_ITEM}}override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {return if (viewType == TYPE_ITEM) {val binding = PaperItemBinding.inflate(LayoutInflater.from(context), parent, false)ViewHolder(binding)} else {val binding =PaperItemFooterBinding.inflate(LayoutInflater.from(context), parent, false)FooterViewHolder(binding)}}override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {super.onAttachedToRecyclerView(recyclerView)val manager = recyclerView.layoutManagerif (manager is GridLayoutManager) {manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {override fun getSpanSize(position: Int): Int {// 如果当前是footer的位置,那么该item占据4个单元格,正常情况下占据1个单元格return if (getItemViewType(position) == TYPE_FOOTER) manager.spanCount else 1}}}}override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {if (holder is ViewHolder) {//处理普通item的逻辑}if (holder is FooterViewHolder) {//处理footerView的逻辑when (loadState) {loading -> {holder.footerBinding.paperLoadingAnim.visibility = View.VISIBLEholder.footerBinding.paperLoadingText.visibility = View.VISIBLEholder.footerBinding.paperBottomText.visibility = View.GONE}loaded -> {holder.footerBinding.paperLoadingAnim.visibility = View.GONEholder.footerBinding.paperLoadingText.visibility = View.GONEholder.footerBinding.paperBottomText.visibility = View.GONE}loadedEnd -> {holder.footerBinding.paperLoadingAnim.visibility = View.GONEholder.footerBinding.paperLoadingText.visibility = View.GONEholder.footerBinding.paperBottomText.visibility = View.VISIBLE}}}}override fun getItemCount() = paperList.size + 1fun setLoadingState(state: Int) {loadState = statenotifyDataSetChanged()}}

在getItemCount我们需要返回数据大小 + 1,来为FooterView腾出位置。可以看到,我们定义了两种布局标志,然后重写getItemViewType方法根据position来设置FooterView,然后在onCreateViewHolder方法中根据不同的ViewType来加载不同的布局。

在这里我采用的是网格布局,所以必须想办法让FooterView横跨我网格的列数。那么在这里需要重写一下onAttachedToRecyclerView方法。首先对当前的布局管理器做一个判断,如果是网格布局,那么需要设置一下spanSizeLookup,网格布局的这个方法代表每个Item占据的单元格数,然后设置在FooterView的情况下占据你设置的列数个单元格,我这里是4。普通Item占据一个单元格就可以了。这样我们就将我们的FooterView设置好了。

下面我们要判断一下什么时候展示FooterView,即滑动到最后一个Item的时候,加载下一页数据。因此我们要对RecyclerView设置滑动监听,代码如下

class BottomRecyclerViewOnScrollerListener : RecyclerView.OnScrollListener() {private var isSlidingUp = falseprivate var onLoadMore: (() -> Unit)? = nulloverride fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {super.onScrollStateChanged(recyclerView, newState)val manager = recyclerView.layoutManager as LinearLayoutManagerif (newState == RecyclerView.SCROLL_STATE_IDLE) {val lastItemPosition: Int = manager.findLastCompletelyVisibleItemPosition()val itemCount = manager.itemCount// 判断是否滑动到了最后一个item,并且是向上滑动if (lastItemPosition == itemCount - 1 && isSlidingUp) {//加载更多onLoadMore?.invoke()}}}override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {super.onScrolled(recyclerView, dx, dy)// 大于0表示正在向上滑动,小于等于0表示停止或向下滑动isSlidingUp = dy > 0}fun setOnLoadMoreListener(listener: () -> Unit) {onLoadMore = listener}
}

代码比较清晰,就不多做解释了,核心就是判断现在是否正在上滑以及是否滑动到了最后一个Item。

只需要给RecyclerView添加监听,做相应的逻辑即可,如下

val bottomListener = BottomRecyclerViewOnScrollerListener()bottomListener.setOnLoadMoreListener {if (paperListAdapter != null) {paperListAdapter!!.setLoadingState(paperListAdapter!!.loading)//请求下一页的逻辑} else {paperListAdapter!!.setLoadingState(paperListAdapter!!.loadedEnd)}}}paperContentView.addOnScrollListener(bottomListener)

那么到这里,其实已经实现了上拉加载的功能,但是这里有一个小坑,就是在第二页请求数据返回之后,必须追加到第一页数据的List上,不可以重新设置Adapter,否则就每刷新一次就会闪到第一行,不符合预期效果。
除此之外,一般上拉加载同时会伴有下拉刷新以及其他筛选刷新的功能,我们使用的数据源必须是一个List才行,要不然处理逻辑会很麻烦,而且往往达不到我们的效果。

RecyclerView实现上拉加载功能相关推荐

  1. 手把手教你实现Android RecyclerView上拉加载功能

    心灵鸡汤:知之者不如好之者,好之者不如乐之者. 摘要 一直在用到RecyclerView时都会微微一颤,因为一直都没去了解怎么实现上拉加载,受够了每次去Github找开源引入,因为感觉就为了一个上拉加 ...

  2. 开发者头条(五):实现recyclerview的上拉加载 + 下拉刷新

    学习Ansen的博客,原文:带你实现开发者头条APP(五)–RecyclerView下拉刷新上拉加载 ,这一篇写的很详细. 知识点 今天主要是实现recyclerview的上拉加载跟多和下拉刷新,依赖 ...

  3. BaseQuickAdapter上拉加载功能实现

    最近使用BaseQuickAdapter进行RecyclerView 的Adapter的数据绑定显示. 实现上拉加载与下拉刷新功能,遇到如下问题: 1.首先是实现下拉刷新.下拉加载的监听(xml布局就 ...

  4. Android使用RecyclerView实现上拉加载更多,下拉刷新,分组显示

    项目地址:点击打开链接(https://github.com/MrGaoGang/luckly_recyclerview) 使用RecyclerView封装headerview,footerView, ...

  5. RecyclerView实现上拉加载更多的正确姿势

    最近项目上的需求需要实现下拉刷新和上拉加载更多的功能,RecyclerView下拉刷新我相信安卓的同学都会做,无非是利用SwipeRefreshLayout,然后给swipeRefreshLayout ...

  6. html 设置移动端页面滚动,a.html · 焚心/移动端页面上下滚动加多页面上拉加载功能及mescroll插件的使用 - Gitee.com...

    我的 我的 交易记录 可兑换签纸贺 兑换历史 活动名称:{{item.title}} 有效期至:{{item.time}} 合计可用额: {{item.price}}元 去兑换 交易记录: 兑换10. ...

  7. js原生实现上拉加载功能

    2019_6_15 js原生实现上拉加载 主要原理是 视图窗口的可视高度,滚动条当前位置,和滚动窗口的高度直接的关系 function SelectCandidatesData(type, page, ...

  8. jquery 实现上拉加载功能

    emmmm,看到了以前自己的写的代码,用jquery实现的上拉加载,顺便修复了以前漏下的bug,感觉可以记录一波. 好的先上图, 好的首先关注console控制台,再来就是右图的内容,页面上初始仅有两 ...

  9. 小程序的上拉加载功能

    小程序页面上拉加载步骤 首先,在需要实现的页面js文件中,创建一个获取请求数据的方法: getdata(bool){let _this = thiswx.showLoading({title: '加载 ...

最新文章

  1. 实战:基于tensorflow 的中文语音识别模型 | CSDN博文精选
  2. 【Solr】- Tomcat部署
  3. 解封装(二):初始化解封装avformat_open_input,各参数分析,以及简单流程
  4. Windows API-GDI入门基础知识详解(1)
  5. 演说时代之艺术创造始于初心
  6. bzoj 1926: [Sdoi2010]粟粟的书架 (主席树+二分)
  7. 关于Android中WebView的点滴
  8. 04 _ 可扩展架构案例(一):电商平台架构是如何演变的?
  9. 微信小程序登陆方式,详细代码步骤如下。
  10. vscdoe常用快捷键
  11. vue 部署上线清除浏览器缓存
  12. 大学计算机基础学后感想,大学计算机基础学习感想
  13. 麻省理工十亿美元计算机学院,麻省理工学院10亿美元打造全新计算机科学学院,让所有学科的研究人员都能接触到最新的计算科学...
  14. 【问题征集】向 iPod 之父、iPhone 联合设计者、Google Nest 创始人 Tony Fadell 提问啦
  15. AOSP、AOKP、CM ROM 究竟有哪些区别?
  16. 从零开始成为优秀的交互设计师
  17. Eigen 求解线性方程组
  18. 南方科技大学2019计算机考研录取,2019浙江硕士研究生拟录取名单_南方科技大学...
  19. 新版火狐 拖 功能_Firefox 33的新功能
  20. 阻止某个程序上网-------防止孩子看抖音快手等视频网站

热门文章

  1. Android知识点复习(持续更新中)
  2. Pulsar Summit Asia 2020 | 英文专场:汇聚全球各地 Pulsar 开发者精彩(下)
  3. 1.29 dup、dup2函数
  4. 最佳 DeFi 代币模型:治理代币 or 生产性代币 or veToken?
  5. 科学计算机程序 字表处理软件都是,计算机应用基础知识123
  6. 什么是列存储?一文秒懂
  7. 安装Naive UI【包含自动导入常用组件】
  8. 【护眼app】护眼宝
  9. unescape弃用后的代替方法
  10. Lily上课时使用字母数字图片教小朋友们学习英语单词,每次都需要把这些图片按照大小(ASCII码值从小到大)排列收好。请大家给Lily帮忙,通过C语言解决。