Recyclerview之瀑布流分割线

本文改进自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;
    }

好了就这么多了。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值