需求说明
RecyclerView做网格布局时,设置RecyclerView的ItemDecoration,要求设置之后:
- 每个item的宽度和高度一致
- 最左边的item左边无间隔
- 最右边的item右边无间隔
分析过程
1. 每个item左右应出比例的计算方式
假定两个view之间需要的间距大小为space
- 如果是两个item,则
- 第一个item:右边出1/2*space的大小
- 第二个item:左边出1/2*space的大小
- 如果是三个item,则
- 第一个item:右边出2/3*space
- 第二个item:左边出1/3space;右边出1/3space
- 第三个item:左边出2/3*space
- 如果是四个item,则
- 第一个item:右边出3/4*space
- 第二个item:左边出1/4space;右边出2/4space
- 第三个item:左边出2/3space;右边出1/4space
- 第四个item:左边出3/4*space
- 归纳总结:有n个item,计算第m个item左右应出的空间的方法
左边=(n-1)/n*space*(m-1)
右边=(n-1)/n*space*(n-m)
分析图:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiATN3IzN1kjNwIjN1ETPw1WY0NXZtlGdk1WZ09mb59jMyITMyEzLcVENGRTO0kTMCVDM4EUQ0IkM1MENyYDM5ADN2UjQChjMvwVZ09mbs1GevwlNkdjMwMDOzETO2IGN1EzM5I2Y1I2YilTY3MjNjR2Ym9CXlNmc192clJ3LcNWasJWdw9CXzdXevwVbvNmLvFGZ19WeuUGdv52Lc9CX6MHc0RHaiojIsJye.jpg)
2. 每个item上下应出比例的计算方式
推理过程如上
SpaceItemDecoration代码如下
/**
* ------------------------------------------------
* Copyright © 2014-2019 CLife. All Rights Reserved.
* Shenzhen H&T Intelligent Control Co.,Ltd.
* -----------------------------------------------
*
* @author huyongming
* @version v1.4.0
* @date 2019/7/2-19:02
* @annotation 通用RecyclerView的分割线;
* 使用注意:需要在notifyDataSetChanged之前,调用setSize(int size, int headerSize)方法,设置RecyclerView中网格部分的item的个数和第一个网格之前的item的个数
*/
public class SpaceItemDecoration extends RecyclerView.ItemDecoration {
private int rowSpace;
private int size;
private int rowSize;
private int headerSize;
private int maxRow;
private float lineSpaceBlank;
private float rowSpaceBlank;
/**
* 构造函数
*
* @param lineSpace 列之间的间隔宽度
* @param rowSpace 行之间的间隔宽度
* @param rowSize 行的大小
*/
public SpaceItemDecoration(int lineSpace, int rowSpace, int rowSize) {
this.rowSpace = rowSpace;
this.rowSize = rowSize;
this.lineSpaceBlank = 1.0f / rowSize * lineSpace;
}
/**
* 设置RecyclerView中网格部分的item的个数和第一个网格之前的item的个数
*
* @param size RecyclerView中网格部分的item的个数
* @param headerSize 第一个网格之前的item的个数
*/
public void setSize(int size, int headerSize) {
this.size = size;
maxRow = (size + rowSize - 1) / rowSize;
this.rowSpaceBlank = 1.0f / maxRow * rowSpace;
this.headerSize = headerSize;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
int position = parent.getChildLayoutPosition(view);
// Logc.d("getChildLayoutPosition:" + position + ";size:" + size + ";headerSize:" + headerSize + ";rowSize:" + rowSize);
if (position + 1 > headerSize && position + 1 - headerSize <= size) {
int realPosition = position - headerSize;
int modePosition = realPosition % rowSize;
outRect.left = (int) (modePosition * lineSpaceBlank);
outRect.right = (int) ((rowSize - 1 - modePosition) * lineSpaceBlank);
int currentRow = realPosition / rowSize;
outRect.top = (int) (currentRow * rowSpaceBlank);
outRect.bottom = (int) ((maxRow - 1 - currentRow) * rowSpaceBlank);
}
}
}