实现带header和footer功能的RecyclerView——完善篇
在上一篇文章中我们实现了实现带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——完善篇相关推荐
- 实现带header和footer功能的RecyclerView
这个项目很简单,其实一年前就开发完成了,但是一直没闲下来去整理. RecyclerView是Android 5.0版本引入的一个新的组件,目的是在一些场景中取代之前ListView和GridView, ...
- delphi 使用cef3谷歌浏览器内核加载带header请求头的网页
上一篇博文介绍到用IE加载带Header请求头的网页,本篇介绍使用cef3实现同样的功能. 我使用的谷歌浏览器内核是49版,支持XP系统的最新版,所以,版本有够低的了. procedure TForm ...
- RecyclerView添加header与footer
前言 这次主要关于RecyclerView添加header和footer的实现方法,我们都知道,在使用ListView的时候我们能自由的给自己的ListView添加头部与尾部.使用addHeaderV ...
- 仿小米相册列表实现自定义带快速索引功能的RecyclerView
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 篇章目标要点 一.实现效果 二.设计布局原理 三.关键代码实现 1.浮标随手势移动 2.浮标随列表移动 3.列表随浮标移动而 ...
- GridView空记录时显示Header和Footer
也有段日子没写什么东西了,也是因为以前闲了好长时间,最近一下又有活干了,也不是什么新任务,还是接着原来没做完的工作重新设计和动工,对原来做好的曲线图形开发一个常用属性的设置,普通用户就可以通过页面对图 ...
- 纯静态网站模板封装header和footer
前后端分离的网站模板,如果不用任何渲染引擎,能否封装公共的header和footer(或其它html公共代码呢)? 答案是肯定的,因为jQuery有一个函数叫 load ,可以在浏览器绘制页面之前加载 ...
- 第七章:Paging添加header和footer
paging使用:https://huangxiaoguo.blog.csdn.net/article/details/106567399 效果 封装可添加Header和Footer的BaseAdap ...
- web前端:main、header、footer、nav、article、section标签的用法
HTML5 添加了诸如main.header.footer.nav.article.section等大量新标签,这些新标签为开发人员提供更多的选择和辅助特性. 默认情况下,浏览器呈现这些新标签的方式与 ...
- VS2013自带的Browser Link功能引发浏览localhost网站时不停的轮询
浏览localhost网站时候不管你打开那个页面它都会不停的轮询.据悉这是VS2013自带的Browser Link功能,里面用到SignalR机制 什么是Browser Link功能,什么是Sign ...
最新文章
- 图灵访谈系列之九:CNode社区谈Node.js技术及生态
- Parallel Python实现程序的并行多cpu多核利用【pp模块】
- 关于mybatis的xml文件中使用 >= 或者 <= 号报错的解决方案
- C语言课程设计选哪个,C语言课程设计选题及要求.docx
- 物流项目宣传活动任务前台分页展示
- css盒模型中margin很牛逼
- 阿里云智能总裁张建锋:保护客户数据安全是第一原则
- 飞书×帆软数知鸟 | 飞书上的一站式需求管理
- flask出现错误:cannot import name ‘ContextVar‘
- Matlab的parfor并行编程
- 从北京77元房租,说说关于房子的事
- k8s升级,HA集群1.12.0~HA集群1.13.2
- 无法打开文件“libboost_system-vc110-mt-gd-x32-1_68.lib”
- 太极root权限_太极iOS 8.4完美越狱曝安全隐患:Root权限易获取
- 计算机维护系统Win8PE,U盘启动计算机维护系统(Win8PEx64内核仅160M)
- Go 开发关键技术指南 | 带着服务器编程金刚经走进 2020 年(内含超全知识大图)
- T3.2是什么级别?
- 基于私钥生成jwt令牌
- CMake入门使用(一)安装及HelloWorld的构建
- 【转载】ASP.Net请求处理机制初步探索之旅 - Part 3 管道