在上一篇文章中我们实现了实现带header和footer功能的RecyclerView,见  实现带header和footer功能的RecyclerView

但是由于加入了header,item的position有了变化,导致了RecyclerView中的一些与position有关方法或使用出现问题。本章着重解决一些常用的方法和使用,至于其他的解决方法类似。

首先,重写几个比较常用的方法,如下:

    @Overridepublic int getChildAdapterPosition(View child) {return super.getChildAdapterPosition(child) - mWrapAdapter.getHeaderCount();}@Overridepublic void swapAdapter(Adapter adapter, boolean removeAndRecycleExistingViews) {mWrapAdapter.setAdapter(adapter);super.swapAdapter(mWrapAdapter, removeAndRecycleExistingViews);}@Overridepublic ViewHolder findViewHolderForAdapterPosition(int position) {return super.findViewHolderForAdapterPosition(position + mWrapAdapter.getHeaderCount());}

总之涉及到item的position的方法和使用都要格外注意,在需要的时候对position进行相应处理。

比如getChildAdapterPosition,我们想知道item的position。但是由于RecyclerView中实际上使用的是WrapAdapter,所以获取的position是包括header的,所以要减去header的数量。

同理,在findViewHolderForAdapterPostion中,我们想通过外部adapter中item的postion获取该item的ViewHolder。实际上我们是要在WrapAdapter中去取,这时考虑到header需要为这个position加上header的数量才能取到正确的ViewHolder。

上面都是比较简单的,复杂一点比如divider。

在列表中我们经常会用到divider,RecyclerView并不像ListView那样可以很简单的添加divider,需要用户自定义一个ItemDecoration。

当我们定义ItemDecoration时就需要注意与position相关的计算,因为一般情况下divider只是给正常的item来使用,header和footer不需要使用(在其布局中已经包含了)。

由于我们一般用比较简单divider就可以了,所以这里实现了一个很简单的默认divider,如果需要自定义参考即可,代码如下:

    public void setTransparentDivider(final int sizePx){addItemDecoration(new ItemDecoration() {@Overridepublic void onDraw(Canvas c, RecyclerView parent, State state) {super.onDraw(c, parent, state);}@Overridepublic void onDrawOver(Canvas c, RecyclerView parent, State state) {super.onDrawOver(c, parent, state);}@Overridepublic void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {int position = ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition();if(mWrapAdapter.isHeader(position) || mWrapAdapter.isFooter(position)){super.getItemOffsets(outRect, view, parent, state);return;}int index = position - mWrapAdapter.getHeaderCount();if(isEnd(parent, index)){if(isVertical(parent)){outRect.set(0, 0, 0, sizePx);}else{outRect.set(0, 0, sizePx, 0);}}else{outRect.set(0, 0, sizePx, sizePx);}}private boolean isVertical(RecyclerView parent){LayoutManager layout = parent.getLayoutManager();if(layout instanceof StaggeredGridLayoutManager){return ((StaggeredGridLayoutManager) layout).getOrientation() == StaggeredGridLayoutManager.VERTICAL;}else if(layout instanceof LinearLayoutManager){return ((LinearLayoutManager) layout).getOrientation() == LinearLayoutManager.VERTICAL;}return true;}private int getSpanCount(RecyclerView parent){LayoutManager layout = parent.getLayoutManager();if(layout instanceof GridLayoutManager){return ((GridLayoutManager) layout).getSpanCount();}if(layout instanceof StaggeredGridLayoutManager){return ((StaggeredGridLayoutManager) layout).getSpanCount();}return 1;}private boolean isEnd(RecyclerView parent, int index){int spanCount = getSpanCount(parent);return (index + 1) % spanCount == 0;}});}

关于ItemDecoration的实现网上有太多的文章了,这里就不细说了。主要说说position相关需要注意的地方。

重点关注getItemOffsets这个方法,通过getViewLayoutPosistion获取的position是item在WrapAdapter中的position。

首先判断是否是header或footer,如果是不添加。

普通的item,由于需要判断是否是一行的最后一个(isEnd,在GridLayoutManager或StaggeredGridLayoutManager中),所以要排除掉header对item位置的影响,这里减去header的数量。

通过上面的处理,header和footer的功能基本完善了,如果遇到其他问题,可以参照上面两种情况进行处理。

这样关于WrapRecyclerView的功能就告一段落了,有关onClickListener的功能很简单,大家看一下源码就明白了。至于更多的功能,我们以后再慢慢补充。

下一章我们会在WrapRecyclerView的基础上实现PullToRefresh,即下拉刷新和上拉加载,敬请期待!

源码

完整源码请关注公众号:BennuCTech,发送“WrapRecyclerView”获取。

实现带header和footer功能的RecyclerView——完善篇相关推荐

  1. 实现带header和footer功能的RecyclerView

    这个项目很简单,其实一年前就开发完成了,但是一直没闲下来去整理. RecyclerView是Android 5.0版本引入的一个新的组件,目的是在一些场景中取代之前ListView和GridView, ...

  2. delphi 使用cef3谷歌浏览器内核加载带header请求头的网页

    上一篇博文介绍到用IE加载带Header请求头的网页,本篇介绍使用cef3实现同样的功能. 我使用的谷歌浏览器内核是49版,支持XP系统的最新版,所以,版本有够低的了. procedure TForm ...

  3. RecyclerView添加header与footer

    前言 这次主要关于RecyclerView添加header和footer的实现方法,我们都知道,在使用ListView的时候我们能自由的给自己的ListView添加头部与尾部.使用addHeaderV ...

  4. 仿小米相册列表实现自定义带快速索引功能的RecyclerView

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 篇章目标要点 一.实现效果 二.设计布局原理 三.关键代码实现 1.浮标随手势移动 2.浮标随列表移动 3.列表随浮标移动而 ...

  5. GridView空记录时显示Header和Footer

    也有段日子没写什么东西了,也是因为以前闲了好长时间,最近一下又有活干了,也不是什么新任务,还是接着原来没做完的工作重新设计和动工,对原来做好的曲线图形开发一个常用属性的设置,普通用户就可以通过页面对图 ...

  6. 纯静态网站模板封装header和footer

    前后端分离的网站模板,如果不用任何渲染引擎,能否封装公共的header和footer(或其它html公共代码呢)? 答案是肯定的,因为jQuery有一个函数叫 load ,可以在浏览器绘制页面之前加载 ...

  7. 第七章:Paging添加header和footer

    paging使用:https://huangxiaoguo.blog.csdn.net/article/details/106567399 效果 封装可添加Header和Footer的BaseAdap ...

  8. web前端:main、header、footer、nav、article、section标签的用法

    HTML5 添加了诸如main.header.footer.nav.article.section等大量新标签,这些新标签为开发人员提供更多的选择和辅助特性. 默认情况下,浏览器呈现这些新标签的方式与 ...

  9. VS2013自带的Browser Link功能引发浏览localhost网站时不停的轮询

    浏览localhost网站时候不管你打开那个页面它都会不停的轮询.据悉这是VS2013自带的Browser Link功能,里面用到SignalR机制 什么是Browser Link功能,什么是Sign ...

最新文章

  1. 图灵访谈系列之九:CNode社区谈Node.js技术及生态
  2. Parallel Python实现程序的并行多cpu多核利用【pp模块】
  3. 关于mybatis的xml文件中使用 >= 或者 <= 号报错的解决方案
  4. C语言课程设计选哪个,C语言课程设计选题及要求.docx
  5. 物流项目宣传活动任务前台分页展示
  6. css盒模型中margin很牛逼
  7. 阿里云智能总裁张建锋:保护客户数据安全是第一原则
  8. 飞书×帆软数知鸟 | 飞书上的一站式需求管理
  9. flask出现错误:cannot import name ‘ContextVar‘
  10. Matlab的parfor并行编程
  11. 从北京77元房租,说说关于房子的事
  12. k8s升级,HA集群1.12.0~HA集群1.13.2
  13. 无法打开文件“libboost_system-vc110-mt-gd-x32-1_68.lib”
  14. 太极root权限_太极iOS 8.4完美越狱曝安全隐患:Root权限易获取
  15. 计算机维护系统Win8PE,U盘启动计算机维护系统(Win8PEx64内核仅160M)
  16. Go 开发关键技术指南 | 带着服务器编程金刚经走进 2020 年(内含超全知识大图)
  17. T3.2是什么级别?
  18. 基于私钥生成jwt令牌
  19. CMake入门使用(一)安装及HelloWorld的构建
  20. 【转载】ASP.Net请求处理机制初步探索之旅 - Part 3 管道

热门文章

  1. 转载的孩子们注意节操哈!!!
  2. android开发学习之路——连连看之游戏逻辑(五)
  3. 安卓移植和驱动开发第八章心得体会
  4. Oracle 11g 之自动收集统计信息
  5. ORACLE——重做日志文件管理
  6. SimpleDateFormat 格式图
  7. 《Java编程艺术》目录
  8. linux安装mysql5.7.19
  9. CentOS 程序开机自启动方法总结
  10. 查看 PHP apache nginx mysql 是如何编译的