概述
RecycleViewUtil
是新增的一个主要针对RecycleView的一个工具类.该工具类中提供了部分RecycleView可能会使用到的方法,其中也包括了一些用来增强HeaderRecycleAdapter
功能的扩展方法.
通过该工具类也可以很容易在普通的adapter中实现对应的相关扩展功能.
可实现的功能有:
- 随意调整RecycleViewAdapter中的item数量
- 可根据RecycleView已确定的某一边长自动调整item数量以填充整个RecycleView(并不再有多余的item)
- 可根据RecycleView已确定的某一边长随意指定需要填充整个RecycleView的item的数量
对于实现的功能如果觉得有点不理解,下面会有更详细的分析.
调整任意数量的item数量
使用过RecycleView的都知道数据部分都是由adapter进行负责的,而item的数量取决于数据量的大小,所以当需要更改item数量时,势必通过调整数据量的大小进行更改.
使用这个原理进行工作的包括给RecycleView添加header/footer等.
- [x] 扩展adapter,支持添加头尾部的ExtraViewWrapAdapter
- [x] 支持分组显示并为每个分组添加一个header的HeaderRecycleaAdapter
而这里调整的方式与之不同的是:
- 数据完全不需要有任何的变化,而是支持对RecycleView中的某个属性进行更改从而实现的调整.
- 该调整方式是通过反射进行的,不需要对控件进行任何继承与修改
关于这个实现的作用最后会给出一个例子参考,在某些情况下还是有实际的需求的.
RecycleView中实际控制item数量的变量
根据之前我们已知的RecycleView的item数量由adapter.getItemCount()
决定,所以直接查找ReccyleView中哪些地方调用了这个方法就可以得到保存item数量的值在哪里了.
//搜索adapter.getItemCount()得到多个方法都有涉及
//分发layout
void dispatchLayout()
//验证viewholder的位置,应该是用于缓存重用部分
boolean validateViewHolderForOffsetPosition(ViewHolder holder)
//测量工作中
void onMeasure(int widthSpec, int heightSpec)
而以上的方法中都是将adapter的itemCount赋值给一个内部成员变量mState
,所以我们简单看看这个State
类型是什么.由于State
虽然不大,但是总代码量也不少,所以只给出我们关注的部分
public static class State {
/**
* Number of items adapter has.
*/
int mItemCount = 0;
}
这里可以看到也有注释,确实mState.mItemCount
是我们我们要找的用于存放itemCount的变量,找到了首先当然看一下它能不能直接赋值或者是处理;很遗憾的是,它对外并不公开(这也是很好理解的,为了安全问题),所以我们需要对其进行修改就只能是通过反射的方式进行了.
在进行反射尝试修改之前,我们先看一下RecycleView中的辅助类ItemDecoration
.看到这个类应该很多人都用过,对RecycleView的分隔线添加什么的都会用这个类进行操作.那么这个类中需要子类重写的方法有几个.
//绘制界面(分隔线等),此部分绘制后item再进行绘制
public void onDraw(Canvas c, RecyclerView parent, State state);
//绘制界面,此部分在所有item绘制会再进行绘制
public void onDrawOver(Canvas c, RecyclerView parent, State state)
关于以上的相关的想进一步了解可以查看一下StickItemDecoration,在这个篇文章中也仔细说明了如何绘制固定头部.
这里可以看到其实参数中就有State
,而在其state.getItemCount()
方法中更是有说明
Returns the total number of items that can be laid out. Note that this number is not necessarily equal to the number of items in the adapter, so you should always use this number for your position calculations and never access the adapter directly.
返回能被布局的总的item数量.请注意此值不一定与adapter.ite