转:http://www.jianshu.com/p/c138055af5d2

一、首先,我们来介绍和分析一下第一种方法,也是网上最多人用的方法:

  1. public static boolean isVisBottom(RecyclerView recyclerView){
  2. LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
  3. //屏幕中最后一个可见子项的position
  4. int lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition();
  5. //当前屏幕所看到的子项个数
  6. int visibleItemCount = layoutManager.getChildCount();
  7. //当前RecyclerView的所有子项个数
  8. int totalItemCount = layoutManager.getItemCount();
  9. //RecyclerView的滑动状态
  10. int state = recyclerView.getScrollState();
  11. if(visibleItemCount > 0 && lastVisibleItemPosition == totalItemCount - 1 && state == recyclerView.SCROLL_STATE_IDLE){
  12. return true;
  13. }else {
  14. return false;
  15. }
  16. }

很明显,当屏幕中最后一个子项lastVisibleItemPosition等于所有子项个数totalItemCount - 1,那么RecyclerView就到达了底部。但是,我在这种方法中发现了极为极端的情况,就是当totalItemCount等于1,而这个子项的高度比屏幕还要高。

item_recycleview.png

看看效果图:

效果图.png

我们可以发现这个子项没完全显示出来就已经被判断为拉到底部。当然,这种方法一般情况下都能满足开发者的需求,只是遇到了强迫症的我~

二、下面我们介绍第二种方法:

  1. public static boolean isSlideToBottom(RecyclerView recyclerView) {
  2. if (recyclerView == null) return false;
  3. if (recyclerView.computeVerticalScrollExtent() + recyclerView.computeVerticalScrollOffset()
  4. >= recyclerView.computeVerticalScrollRange())
  5. return true;
  6. return false;
  7. }

这种方法原理其实很简单,而且也是View自带的方法。

原理图.png

这样就很清晰明了,computeVerticalScrollExtent()是当前屏幕显示的区域高度,computeVerticalScrollOffset() 是当前屏幕之前滑过的距离,而computeVerticalScrollRange()是整个View控件的高度。
这种方法经过测试,暂时还没发现有bug,而且它用的是View自带的方法,所以个人觉得比较靠谱。

三、下面讲讲第三种方法:

  1. RecyclerView.canScrollVertically(1)的值表示是否能向上滚动,false表示已经滚动到底部
  2. RecyclerView.canScrollVertically(-1)的值表示是否能向下滚动,false表示已经滚动到顶部

这种方法更简单,就通过简单的调用方法,就可以得到你想要的结果。我一讲过这种方法与第二种方法其实是同一种方法,那下面来分析一下,看看canScrollVertically的源码:

canScrollVertically的源码

是不是一目鸟然了,canScrollVertically方法的实现实际上运用到的是方法二的三个函数,只是这个方法Android已经帮我们封装好了,原理一模一样的。
本人现在也是运用了这种方法做判断的~懒人~工具类都省了~

四、最后一种方法其实是比较呆板的,就是利用LinearLayoutManager的几个方法,1.算出已经滑过的子项的距离,2.算出屏幕的高度,3.算出RecyclerView的总高度。然后用他们做比较,原理类似于方法二。

  1. public static int getItemHeight(RecyclerView recyclerView) {
  2. int itemHeight = 0;
  3. View child = null;
  4. LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
  5. int firstPos = layoutManager.findFirstCompletelyVisibleItemPosition();
  6. int lastPos = layoutManager.findLastCompletelyVisibleItemPosition();
  7. child = layoutManager.findViewByPosition(lastPos);
  8. if (child != null) {
  9. RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
  10. itemHeight = child.getHeight() + params.topMargin + params.bottomMargin;
  11. }
  12. return itemHeight;}

算出一个子项的高度

  1. public static int getLinearScrollY(RecyclerView recyclerView) {
  2. int scrollY = 0;
  3. LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
  4. int headerCildHeight = getHeaderHeight(recyclerView);
  5. int firstPos = layoutManager.findFirstVisibleItemPosition();
  6. View child = layoutManager.findViewByPosition(firstPos);
  7. int itemHeight = getItemHeight(recyclerView);
  8. if (child != null) {
  9. int firstItemBottom = layoutManager.getDecoratedBottom(child);
  10. scrollY = headerCildHeight + itemHeight * firstPos - firstItemBottom;
  11. if(scrollY < 0){
  12. scrollY = 0;
  13. }
  14. }
  15. return scrollY;
  16. }

算出滑过的子项的总距离

  1. public static int getLinearTotalHeight(RecyclerView recyclerView) { int totalHeight = 0;
  2. LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
  3. View child = layoutManager.findViewByPosition(layoutManager.findFirstVisibleItemPosition());
  4. int headerCildHeight = getHeaderHeight(recyclerView);
  5. if (child != null) {
  6. int itemHeight = getItemHeight(recyclerView);
  7. int childCount = layoutManager.getItemCount();
  8. totalHeight = headerCildHeight + (childCount - 1) * itemHeight;
  9. }
  10. return totalHeight;
  11. }

算出所有子项的总高度

  1. public static boolean isLinearBottom(RecyclerView recyclerView) {
  2. boolean isBottom = true;
  3. int scrollY = getLinearScrollY(recyclerView);
  4. int totalHeight = getLinearTotalHeight(recyclerView);
  5. int height = recyclerView.getHeight();
  6. // Log.e("height","scrollY " + scrollY + " totalHeight " + totalHeight + " recyclerHeight " + height);
  7. if (scrollY + height < totalHeight) {
  8. isBottom = false;
  9. }
  10. return isBottom;
  11. }

判断RecyclerView是否滚动到底部的更多相关文章

  1. js 判断浏览器是否滚动到底部

    //jquery 实现代码 $(document).height() == $(window).height() + $(window).scrollTop() 1 整个空间的高度 包含(滚动条距离顶 ...

  2. vue 判断页面是否滚动到底部

    需求 要求用户阅读完本页所有内容后,下一步按钮才可以点击. 实现思路 通过判断当前页面是否到达底部来设置按钮的点击事件. 要判断当前页面是否到达底部需要用到三个距离--距离顶部的距离scrollTop ...

  3. 判断RecyclerView到达底部的几种方法

    参考文章:https://www.jianshu.com/p/c138055af5d2 1.比较lastItem的pos 通过比较当前屏幕可见最后一个item的position和整个RV的最后一个it ...

  4. 不同浏览器对document.documentElement和document.body的scrollheight ,scrollTop,clientHeight以及判断滚动条是否滚动到页面最底部 【转载】

    前段时间学习怎么写一个瀑布流的时候,就接触到document.documentElement和document.body的区别,然后今天查资料的时候看到这篇博客,遂转载记录在此. 两种特殊的文档属性可 ...

  5. android ListView滚动条监听判断滚动到底部还是顶部

    代码: lv.setOnScrollListener(new OnScrollListener() { public void onScrollStateChanged(AbsListView vie ...

  6. ListView滚动到底部判断

    参考:http://blog.csdn.net/jodan179/article/details/8017693 List13介绍的是ListView.OnScrollListener的 onScro ...

  7. XRecyclerView:实现下拉刷新、滚动到底部加载更多以及添加header功能的RecyclerView

    介绍: 一个实现了下拉刷新,滚动到底部加载更多以及添加header功能的的RecyclerView.使用方式和RecyclerView完全一致,不需要额外的layout,不需要写特殊的adater. ...

  8. RecyclerView的滚动事件OnScrollListener研究

      (1)滚动事件分类 列表的滚动一般分为两种: 1.手指按下 -> 手指拖拽列表移动 -> 手指停止拖拽 -> 抬起手指 2.手指按下 -> 手指快速拖拽后抬起手指 -> ...

  9. 页面滚动到底部自动 Ajax 获取文章

    页面滚动到底部自动 Ajax 获取文章  代码如下 复制代码 var _timer = {};function delay_till_last(id, fn, wait) {    if (_time ...

随机推荐

  1. Flask【第9篇】:Flask-script组件

    flask-script组件 Flask Script扩展提供向Flask插入外部脚本的功能,包括运行一个开发用的服务器,一个定制的Python shell,设置数据库的脚本,cronjobs,及其他 ...

  2. Hystrix——让你的服务更稳一点

    摘要: 1.为什么要用Hystrix在分布式服务环境下,服务之间的调用关系变得错综复杂,你是否担心依赖的服务延迟导致自己的服务也被拖跨呢?是否在苦苦思考如何优雅的对依赖服务进行异步调用呢?是否希望当流 ...

  3. Electron开发使用Vue Devtools

    转自 [https://orchidflower.oschina.io/2017/03/29/Using-Vue-Devtools-in-Electron/] 2.2 安装步骤 首先在Chrome中安 ...

  4. css---一个大div中套左右两个div,如何让最高的把最低的撑开?且把父级撑开呢?

    到最后实现了效果,但是在理论上感觉还是很牵强,如果哪位大神有方法,请评论指出哦 Html: css:

  5. C/C++运算符优先级关系

    C/C++优先级 从高到低 1~14梯队 1.  ()  []  .  -> 2.   !  ~   -(负号) ++  --   &(取变量地址)*   (type)(强制类型)   ...

  6. HTML5测试(一)

    HTML5测试一 1. 问题:HTML5 之前的 HTML 版本是什么? A.HTML 4.01 B.HTML 4 C.HTML 4.1 D.HTML 4.9 答案:A HTML5 是 HTML 最新 ...

  7. Codeforces 950D A Leapfrog in the Array ( 思维 && 模拟 )

    题意 : 给出 N 表示有标号 1~N 的 N 个数,然后从下标 1 开始将这 N 个数每隔一位放置一个,直到 N 个数被安排完,现在有一个操作就是每次将数列中最右边的数向离其左边最近的空缺处填上,一 ...

  8. pycharm 安装激活

    下载pycharm :http://www.jetbrains.com/pycharm/download/download 安装 直到 finish 下载补丁jetbrains-agent.jar并添 ...

  9. spring cloud:config-eureka-refresh-bus-rabbitmq

    config-server-eureka-bus-rabbitmq 1. File-->new spring starter project 2.add dependency <paren ...

  10. yii2.0 curd操作数据写法

    一.执行原生sql查询,创建yii\db\Command         insert(),update(),delete()直接构建,相应的sql语句 查: 1.查询一条 \Yii::$app-&g ...