• 判断RecyclerView是否滚动到底部


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

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

    public static boolean isVisBottom(RecyclerView recyclerView){  
      LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();  
      //屏幕中最后一个可见子项的position
      int 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,而这个子项的高度比屏幕还要高。


    item_recycleview.png


    看看效果图:


    效果图.png


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

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

    public static boolean isSlideToBottom(RecyclerView recyclerView) {    
       if (recyclerView == null) return false; 
       if (recyclerView.computeVerticalScrollExtent() + recyclerView.computeVerticalScrollOffset() 
            >= recyclerView.computeVerticalScrollRange())   
         return true;  
       return false;
    }

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


    原理图.png


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

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

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

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


    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;
    }
  • 相关阅读:
    js转换文件的size由KB转换为B、MB、GB
    SMW0 对应 MIME TYPE 无法包进请求上传
    SynapseML MMLSpark 集群 机器学习 训练
    Ribbon七种负载均衡策略详解
    restcontroller的作用
    跨域的实现方法
    Unknown collation: ‘utf8mb4_0900_ai_ci‘ 的解决方案
    Redis Template及4种序列化方式
    二维数组排序JS
    ad域&NTLM(浏览网址)
  • 原文地址:https://www.cnblogs.com/jdhdevelop/p/6743501.html
Copyright © 2020-2023  润新知