天天看点

Recyclerview之瀑布流分割线

本文改进自Recyclerview之瀑布流分割线左右间距均等问题

根据这篇文章的设置以后,显示效果如下:

Recyclerview之瀑布流分割线

这样显示时没有问题的。

可是当我改成3列时:

Recyclerview之瀑布流分割线

很明显,分割线错乱了。

因为代码里写死了列数

/**
         * 根据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改成变量就可以了? 并不是。

我们回过头来想一想,无论是瀑布流还是网格布局,我们所需要处理的只是最左边和最右边的分割线,不管是多少列,中间有多少,中间的部分左右都是一半的间距。

Recyclerview之瀑布流分割线

所以我们只需要知道当前的View是在哪个位置即可。是在最左边还是中间的还是最右边的。

那么下面从当前View的position入手。

经过一番比划,我发现如下规律:

position : 当前位置

column:列数

row :行数 = position/column +1

最左边的 : column*row - position = column

最右边的 : column*row - position = 1

那么按照这个方法设置之后,得到的结果,依然如图2所示。

这是为什么呢?

Recyclerview之瀑布流分割线

原来瀑布流是从上面布局最短处开始的。

白忙活,回过头再看看这个是啥玩意 

StaggeredGridLayoutManager.LayoutParams params =
                (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
        // 当前位置
        int position = params.getSpanIndex();
           

日志如下:

Recyclerview之瀑布流分割线

这玩意不就是我们要的位置吗?

那剩下的就简单了

@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;
    }
           

最后看看效果:

Recyclerview之瀑布流分割线

4列呢?

Recyclerview之瀑布流分割线

然而,当为1列时:

Recyclerview之瀑布流分割线

这时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;
    }
           

好了就这么多了。