美文网首页android
Android 使用Recyclerview轻松实现顶部悬浮栏

Android 使用Recyclerview轻松实现顶部悬浮栏

作者: I呀IT小胖 | 来源:发表于2017-01-05 00:15 被阅读3689次

    <blockquote>
    用这个方式实现有很大的局限性, 粗糙的解释一下, 在recyclerView上套一层和itemView 上一样的head的布局, 再滑动的时候动态设置套在recyclerView上布局即可(见下图)
    </blockquote>

    normalHead.png

    <blockquote>
    标题栏以下就是recyclerView+normalHead 的布局, item的布局的head必须要跟normalHead的布局一模一样,如果不一样则实现不了需求.
    详细见底下代码,github地址 https://github.com/zhangshuqi/StickyHeadRecyclerView
    </blockquote>

     rvContent.addOnScrollListener(new RecyclerView.OnScrollListener() {        
          @Override      
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {      
                  super.onScrollStateChanged(recyclerView, newState);         
                 // 当recyclerView的滑动改变改变的时候 实时拿到它的高度         
                 headHeight = normalHead.getHeight();    
        }        
          @Override    
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {       
                   super.onScrolled(recyclerView, dx, dy);  
              // 根据当前的position的下一个拿到view         
               View itemView = linearLayoutManager.findViewByPosition(mCurrentPosition + 1);        
              if (itemView != null) {             
               // 通过itemView 顶部y 坐标  判断是否小于或者等于head的底部y坐标,成立的话,就说明itemViewHead已经和normalHead开始接触了.
              // 就开始对NormalHead 进行操作        
                 if (itemView.getTop() <= headHeight) {          
    // 下面有详细解释
                     normalHead.setY(-(headHeight - itemView.getTop()));       
                 } else {                       
                     normalHead.setY(0);                 
            }      
          }       
                 //拿到当前第一个显示的item的position          
                int currentPosition = linearLayoutManager.findFirstVisibleItemPosition();  
              // 如果不等于的话, 就说明当前mCurrentPosition 的 (上滑)上一个已经隐藏或者是(下滑)下一个已经完全显示了,就要做重新赋值的操作了. 
                if (mCurrentPosition != currentPosition) {              
                  mCurrentPosition = currentPosition;              
                  normalHead.setY(0);           
                 // 拿到当前item的head值,显示在normalHead上     
                   normalHead.setText(data.get(mCurrentPosition ).text + (mCurrentPosition + 1));      
          }     
       }   
     });
    }
    

    <blockquote>
    主要的逻辑代码在于

    1, View itemView = linearLayoutManager.findViewByPosition(mCurrentPosition + 1); 拿到当前position的下一个item的view
    2 . if (itemView.getTop() <= headHeight) normalHead.setY(-(headHeight - itemView.getTop()));
    判断下一个的item的top值是不是小于normalHead的高度,

    如果成立
    则分成两种情况
    上滑 : -(headHeight - itemView.getTop())将为负值, normalHead则逐渐隐藏
    下滑 : -(headHeight - itemView.getTop())将为正值, normalHead不断的往下移,当前显示的item的head不断被滑下

    如果不成立 则 说明 上滑或者下滑的top值已经大于了normalHead的高度了, 则说明不需要移动了,将normalHead固定在顶部
    normalHead.setY(0);

    3, int currentPosition = linearLayoutManager.findFirstVisibleItemPosition(); 拿到当前显示的第一个position
    4 if (mCurrentPosition != currentPosition)
    如果不等于的话, 就说明当前mCurrentPosition 的 (上滑)normalHead已经完全隐藏或者是(下滑)itemView的Head已经完全显示了,就要对normalHead重新赋值并且固定在顶部了

    </blockquote>

    <blockquote>

    这段代码难度不大,但是理解起来还是有点儿复杂,主要代码就是这么一段,实际上就是监听recyclerView的滑动,当normalHead和itemView的head接触的时候,隐藏和显示并且对normalHead的值进行操作, 说白了,就是一个偷梁换柱的过程,有两个相同的head一起盖着呢...

    所以说 这个实现过程虽然简单, 就是有其局限性就是normalHead和itemView的head的布局都要一模一样, 不然是实现不了的

    希望我的注释能够帮到同学们,如果有些难以理解, 或者我的注释写的不够完善,(我表达不大行....感觉好多东西都是只可意会不可言传.....) 请到我的github上下载看一下(可以把fresco的依赖去掉写个imageView足以实现需求.)
    github地址 https://github.com/zhangshuqi/StickyHeadRecyclerView
    有疑问或者是建议的同学可以评论讨论一下, 谢谢
    </blockquote>

    相关文章

      网友评论

        本文标题:Android 使用Recyclerview轻松实现顶部悬浮栏

        本文链接:https://www.haomeiwen.com/subject/dlysmttx.html