总结和分析几种判断RecyclerView到达底部的方法
上一篇文章我讲到用事件分发的原理结合SwipeRefreshLayout写一个RecyclerView的上下拉,里面有一个判断RecyclerView是否到达底部的方法isBottom。我的同事用了这个上下拉之后发现有些小bug,没考虑周全,譬如各个子项高度不统一的时候,然后我找到原因是因为这个判断上下拉的问题。所以,我就去网上查到几种判断RecyclerView到达底部的方法,发现各有千秋。以下的分析都以上一篇文章的SwipeRecyclerView为例。
1.lastVisibleItemPosition == totalItemCount - 1判断;
2.computeVerticalScrollRange()等三个方法判断;
3.canScrollVertically(1)判断;
4.利用RecyclerView的LinearLayoutManager几个方法判断。
其实,第2和第3种是属于同一种方法,在下面的分析会讲到。
一、首先,我们来介绍和分析一下第一种方法,也是网上最多人用的方法:
public static boolean isVisBottom(RecyclerView recyclerView){ LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); //屏幕中最后一个可见子项的positionint lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition(); //当前屏幕所看到的子项个数int visibleItemCount = layoutManager.getChildCount(); //当前RecyclerView的所有子项个数int totalItemCount = layoutManager.getItemCount(); //RecyclerView的滑动状态int state = recyclerView.getScrollState(); if(visibleItemCount > 0 && lastVisibleItemPosition == totalItemCount - 1 && state == recyclerView.SCROLL_STATE_IDLE){ return true; }else { return false; }
}
很明显,当屏幕中最后一个子项lastVisibleItemPosition等于所有子项个数totalItemCount - 1,那么RecyclerView就到达了底部。但是,我在这种方法中发现了极为极端的情况,就是当totalItemCount等于1,而这个子项的高度比屏幕还要高。
看看效果图:
我们可以发现这个子项没完全显示出来就已经被判断为拉到底部。当然,这种方法一般情况下都能满足开发者的需求,只是遇到了强迫症的我~
二、下面我们介绍第二种方法:
public static boolean isSlideToBottom(RecyclerView recyclerView) { if (recyclerView == null) return false; if (recyclerView.computeVerticalScrollExtent() + recyclerView.computeVerticalScrollOffset() >= recyclerView.computeVerticalScrollRange()) return true; return false;
}
这种方法原理其实很简单,而且也是View自带的方法。
这样就很清晰明了,computeVerticalScrollExtent()是当前屏幕显示的区域高度,computeVerticalScrollOffset() 是当前屏幕之前滑过的距离,而computeVerticalScrollRange()是整个View控件的高度。
这种方法经过测试,暂时还没发现有bug,而且它用的是View自带的方法,所以个人觉得比较靠谱。
三、下面讲讲第三种方法:
RecyclerView.canScrollVertically(1)的值表示是否能向上滚动,false表示已经滚动到底部
RecyclerView.canScrollVertically(-1)的值表示是否能向下滚动,false表示已经滚动到顶部
这种方法更简单,就通过简单的调用方法,就可以得到你想要的结果。我一讲过这种方法与第二种方法其实是同一种方法,那下面来分析一下,看看canScrollVertically的源码:
是不是一目鸟然了,canScrollVertically方法的实现实际上运用到的是方法二的三个函数,只是这个方法Android已经帮我们封装好了,原理一模一样的。
本人现在也是运用了这种方法做判断的懒人工具类都省了~
四、最后一种方法其实是比较呆板的,就是利用LinearLayoutManager的几个方法,1.算出已经滑过的子项的距离,2.算出屏幕的高度,3.算出RecyclerView的总高度。然后用他们做比较,原理类似于方法二。
public static int getItemHeight(RecyclerView recyclerView) { int itemHeight = 0; View child = null; LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); int firstPos = layoutManager.findFirstCompletelyVisibleItemPosition(); int lastPos = layoutManager.findLastCompletelyVisibleItemPosition(); child = layoutManager.findViewByPosition(lastPos); if (child != null) { RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); itemHeight = child.getHeight() + params.topMargin + params.bottomMargin; } return itemHeight;}
算出一个子项的高度
public static int getLinearScrollY(RecyclerView recyclerView) { int scrollY = 0; LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); int headerCildHeight = getHeaderHeight(recyclerView); int firstPos = layoutManager.findFirstVisibleItemPosition(); View child = layoutManager.findViewByPosition(firstPos); int itemHeight = getItemHeight(recyclerView); if (child != null) { int firstItemBottom = layoutManager.getDecoratedBottom(child); scrollY = headerCildHeight + itemHeight * firstPos - firstItemBottom; if(scrollY < 0){ scrollY = 0; } } return scrollY;
}
算出滑过的子项的总距离
public static int getLinearTotalHeight(RecyclerView recyclerView) { int totalHeight = 0; LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); View child = layoutManager.findViewByPosition(layoutManager.findFirstVisibleItemPosition()); int headerCildHeight = getHeaderHeight(recyclerView); if (child != null) { int itemHeight = getItemHeight(recyclerView); int childCount = layoutManager.getItemCount(); totalHeight = headerCildHeight + (childCount - 1) * itemHeight; } return totalHeight;
}
算出所有子项的总高度
public static boolean isLinearBottom(RecyclerView recyclerView) {
boolean isBottom = true; int scrollY = getLinearScrollY(recyclerView); int totalHeight = getLinearTotalHeight(recyclerView); int height = recyclerView.getHeight();// Log.e("height","scrollY " + scrollY + " totalHeight " + totalHeight + " recyclerHeight " + height); if (scrollY + height < totalHeight) { isBottom = false; } return isBottom;
}
高度作比较
虽然这种方法看上去比较呆板的同时考虑不很周全,但这种方法可以对RecylerView的LinearLayoutManager有深一步的理解,这也是我的师兄给我提供的一个借鉴的类,我非常感谢他!有兴趣的同学可以去下载源码的做进一步的研究,发现有更好玩的方法可以一起研究!
源码下载链接
作者:19snow93
链接:https://www.jianshu.com/p/c138055af5d2
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
总结和分析几种判断RecyclerView到达底部的方法相关推荐
- Excel:5种判断奇数和偶数的方法
整数中,能被2整除的数是偶数(英文:EVEN,数学术语),不能被2整除的数是奇数(英文:ODD,数学术语),偶数可用2k表示,奇数可用2k+1表示,这里k是整数.0是一个特殊的偶数.那么,该如何使用E ...
- Java判断三个球的大中小_玩进球数有门道 三种判断大小球的典型方法
竞彩进球数玩法是竞彩一个主要玩法,比半全场更加受欢迎.因为很多彩民习惯了大小球玩法,因此,作为大球的变种,进球数受到这部分彩民的热捧.不过,市面上介绍亚盘的方法较多,介绍判断大小球的方法却很少.为此, ...
- 在vue中如何判断滚动条到达底部
mounted(){//在生命周期函数mounted中console.log(this.$refs.veriface,'智能切分滚动组件实例')//具有滚动条的dom元素,this.$refs.ver ...
- 如何判断无法到达目标的拼图_拼图项目的动机和目标
如何判断无法到达目标的拼图 几周前,我写了一篇关于Jigsaw项目可能如何破坏现有代码的文章 . 那么我们得到什么回报呢? 让我们看一下项目解决的痛点及其在Java 9中解决问题的目标. 系列 这篇文 ...
- 逐步认识C#四种判断相等的方法
C#有四种判断相等的方法?不少人看到这个标题,会对此感到怀疑.事实上确是如此,.Net提供了ReferenceEquals.静态Equals,具体类型的Equals以及==操作符这四个判等函数.但是这 ...
- 7-32 哥尼斯堡的“七桥问题” (25 分)(思路+详解+题目分析)两种做法任选其一
一:题目: 哥尼斯堡是位于普累格河上的一座城市,它包含两个岛屿及连接它们的七座桥,如下图所示. 可否走过这样的七座桥,而且每桥只走过一次?瑞士数学家欧拉(Leonhard Euler,1707-178 ...
- sql查询当天交易总额最大的用户信息_如何分析交易记录? 因为后面要分析“每种类型用户的总交易金额”,所以保留左表(用户交易记录表)中的全部用户数据。 【题目】 某商场为了分析用... - 雪球...
来源:雪球App,作者: 猴子数据分析,(https://xueqiu.com/1350621016/159703178) 因为后面要分析"每种类型用户的总交易金额",所以保留左表 ...
- 关于定义域有界性的三种判断
关于定义域有界性的三种判断 @(微积分) 给定一个函数,讨论其在定义域上是否有界,有三种方法.不敢说常见,提出来思考. 理论法:若f(x)在定义域[a,b]上连续,或者放宽到常义可积(有限个第一类间断 ...
- (笔记)两种判断奇数偶数的方法
(笔记)两种判断奇数偶数的方法 学习的需要,查找了如何判断奇偶数的方法,自己做了以下笔记. 方法来自网络,已标明出处. 方法一 .求余% 具体实现: 1.if( x % 2 ) // 奇数 ...
最新文章
- 2017.12.20-21
- LeetCode 840. 矩阵中的幻方(数学)
- windows mobile 服务自动停止_打印服务print Splooer自动停止怎么办?
- 你的个人信息真的被偷走了?——那些过分“精准”的广告推荐的背后
- 剑指 Offer II 036. 后缀表达式
- mysql hy000 2013_MySQLERROR2013(HY000)错误解决方法
- Eclipse快捷键_10个最高效的快捷键
- 进程/线程间通信和同步
- 使用Jacob自动替换书签内容
- Xshell 7官网免费版下载与安装(详细教程)
- 邮件营销如何“爆增”潜在客户?
- 关系代数 元组关系演算
- android textview html font标签不好用
- 随机漫步python程序
- bigworld游戏服务器架构参考
- 33个高能CSS选择器让我受益匪浅
- python图片转文字easyocr_OCR识别软件将图片转文字的具体方法
- LaTeX 插入PDF图片,该用哪个命令?
- CCF-CSP 202112-3登机牌条码 解题思路+满分题解+详细注释
- 莫烦python系列教程_莫烦python教程学习笔记——总结篇
热门文章
- python程序调试logging_python-logging模块的简单使用
- 类成员_月隐学python第17课
- python多线程共享全局变量_Python多线程-共享全局变量
- c语言电子计算器课程设计报告,计算机程序设计课程设计报告.doc
- 下次激活策略10_服装店营销策划方案,简单策略让服装超市提升10倍业绩
- 20220207-CTF-MISC-第11题--- base64隐写--附带脚本
- html中地图的绘制toolbars,三维GIS实验一:Surfer8地理信息制图.doc
- 接口测试学习——jmeter分布式压测
- python多线程理解
- 不用asp.net MVC,用WebForm照样能够实现MVC