本文改进自Recyclerview之瀑布流分割线左右间距均等问题
根据这篇文章的设置以后,显示效果如下:

这样显示时没有问题的。
可是当我改成3列时:
很明显,分割线错乱了。
因为代码里写死了列数
/**
* 根据params.getSpanIndex()来判断左右边确定分割线
* 第一列设置左边距为space,右边距为space/2 (第二列反之)
*/
if (params.getSpanIndex() % 2 == 0) {
outRect.left = space;
outRect.right = space / 2;
} else {
outRect.left = space / 2;
outRect.right = space;
}
那把里面的2改成变量就可以了? 并不是。
我们回过头来想一想,无论是瀑布流还是网格布局,我们所需要处理的只是最左边和最右边的分割线,不管是多少列,中间有多少,中间的部分左右都是一半的间距。
所以我们只需要知道当前的View是在哪个位置即可。是在最左边还是中间的还是最右边的。
那么下面从当前View的position入手。
经过一番比划,我发现如下规律:
position : 当前位置
column:列数
row :行数 = position/column +1
最左边的 : column*row - position = column
最右边的 : column*row - position = 1
那么按照这个方法设置之后,得到的结果,依然如图2所示。
这是为什么呢?
原来瀑布流是从上面布局最短处开始的。
白忙活,回过头再看看这个是啥玩意
StaggeredGridLayoutManager.LayoutParams params =
(StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
// 当前位置
int position = params.getSpanIndex();
日志如下:
这玩意不就是我们要的位置吗?
那剩下的就简单了
@Override
public void getItemOffsets(Rect outRect, View view,
RecyclerView parent, RecyclerView.State state) {
StaggeredGridLayoutManager.LayoutParams params =
(StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
// 当前位置
int position = params.getSpanIndex();
int X = column - position;
if(X == column){
// 最左边
outRect.left = space;
outRect.right = halfSpace;
}else if(X == 1){
// 最右边
outRect.left = halfSpace;
outRect.right = space;
}else{
outRect.left = halfSpace;
outRect.right = halfSpace;
}
outRect.bottom = space;
}
最后看看效果:
4列呢?
然而,当为1列时:
这时position一直都是为0,永远都是最左边的状态。
所以这里得改一下:
@Override
public void getItemOffsets(Rect outRect, View view,
RecyclerView parent, RecyclerView.State state) {
outRect.left = space;
outRect.right = space;
if (column != 1) {
StaggeredGridLayoutManager.LayoutParams params =
(StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
// 当前位置
int position = params.getSpanIndex();
int X = column - position;
if (X == column) {
// 最左边
outRect.right = halfSpace;
} else if (X == 1) {
// 最右边
outRect.left = halfSpace;
} else {
outRect.left = halfSpace;
outRect.right = halfSpace;
}
}
outRect.bottom = space;
}
至于第一行顶部要不要加自行判断吧。
网格的话这里改一下也是可以直接使用的。
@Override
public void getItemOffsets(Rect outRect, View view,
RecyclerView parent, RecyclerView.State state) {
outRect.left = space;
outRect.right = space;
if (column != 1) {
int position;
if(parent.getLayoutManager() instanceof StaggeredGridLayoutManager){
StaggeredGridLayoutManager.LayoutParams params =
(StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
// 当前位置
position = params.getSpanIndex();
}else{
GridLayoutManager.LayoutParams params = (GridLayoutManager.LayoutParams) view.getLayoutParams();
position = params.getSpanIndex();
}
int X = column - position;
if (X == column) {
// 最左边
outRect.right = halfSpace;
} else if (X == 1) {
// 最右边
outRect.left = halfSpace;
} else {
outRect.left = halfSpace;
outRect.right = halfSpace;
}
}
outRect.bottom = space;
}
好了就这么多了。