<android>RecyclerView使用GridLayoutManager间距均分等分问题,不要修改xml了太麻烦,一行代码适配所有

///  更新代码  //

更新:当重写onAttachedToRecyclerView方法后,对Item一行单个、一行多个共存的情况下的适配。

/**
 * title: recyclerview设置GridLayoutManager 等分margin宽度时的自定义ItemDecoration
 * AdapterRange:一个一行n个item、多个一行n个item
 * author:LG
 */
public class RecyclerViewMarginDecoration extends RecyclerView.ItemDecoration {
    private int mMargin;
    int spanCount;
    private int mOrderPostion;
    private boolean isPullUp;
    int topPostion = -1;
    int childLayoutOuPosition = 0;
    int childLayoutJiPosition = 0;

    /**
     * @param context   上下文
     * @param spanCount 每行的item数量
     * @param margin    均宽的magin值
     */
    public RecyclerViewMarginDecoration(Context context, int spanCount, int margin) {
        mMargin = ScreenUtil.dpAdapt((Activity) context, margin, Contact.DESGINWIDTH);
        this.spanCount = spanCount;
    }


    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {

        RecyclerView.LayoutManager manager = parent.getLayoutManager();
        if (manager instanceof GridLayoutManager) {
            final GridLayoutManager gridManager = ((GridLayoutManager) manager);
            GridLayoutManager.SpanSizeLookup spanSizeLookup = gridManager.getSpanSizeLookup();
            int spanSize = spanSizeLookup.getSpanSize(parent.getChildAdapterPosition(view));
            if (spanSize == 1) {
                //找到第一个开始位置  判断第一个item是基数还是偶数
                if ((parent.getChildLayoutPosition(view)) % spanCount == 0 && topPostion == -1) {
                    topPostion = parent.getChildLayoutPosition(view);
                } else if ((parent.getChildLayoutPosition(view)) % spanCount != 0 && topPostion == -1) {
                    topPostion = parent.getChildLayoutPosition(view);
                }

                //此处parent.getChildLayoutPosition(view))会有一个正序和反序,对应上划和下划,需要区分,因为我们下边会根据当前item的postion做条件设置合适的magin
                isPullUp = parent.getChildLayoutPosition(view) > mOrderPostion;
                mOrderPostion = parent.getChildLayoutPosition(view);

                //根据奇偶数来改变内部判断条件 区分是单纯的一个一行n个item,还是多个一行n个item
                if (topPostion % spanCount == 0) {
                    if ((parent.getChildLayoutPosition(view)) % spanCount == 0) {
                        outRect.set(mMargin, 0, mMargin / 2, 0);
                        childLayoutOuPosition = parent.getChildLayoutPosition(view);
                    } else {
                        //根据正反序找到这一行的最后一个item位置  加载示例:上拉 0 1  2 3  4 5  下拉: 3 2 1 0
                        int lastItem=isPullUp? childLayoutOuPosition + spanCount - 1:parent.getChildLayoutPosition(view);
                        if ((parent.getChildLayoutPosition(view)) == lastItem) {
                            outRect.set(mMargin / 2, 0, mMargin, 0);
                        } else {
                            outRect.set(mMargin / 2, 0, mMargin / 2, 0);
                        }
                    }

                } else {
                    if ((parent.getChildLayoutPosition(view)) % spanCount != 0) {
                        outRect.set(mMargin, 0, mMargin / 2, 0);
                        childLayoutJiPosition = parent.getChildLayoutPosition(view);
                    } else {
                        int lastItem = isPullUp ? childLayoutJiPosition + spanCount - 1 : parent.getChildLayoutPosition(view);
                        if ((parent.getChildLayoutPosition(view)) == lastItem) {
                            outRect.set(mMargin / 2, 0, mMargin, 0);
                        } else {
                            outRect.set(mMargin / 2, 0, mMargin / 2, 0);
                        }
                    }
                }
            }
        }
    }
}

使用:

recyclerview.addItemDecoration(new RecyclerViewMarginDecoration(this,2,15));

/以下旧版本不推荐
/**
 * recyclerview设置GridLayoutManager 等分margin宽度时的自定义ItemDecoration
 */
public class RecyclerViewMarginDecoration extends RecyclerView.ItemDecoration {

private int mMargin;
int spanCount;

    /**
     * @param context   上下文
     * @param spanCount 每行的item数量
     * @param margin    均宽的magin值
     */
public RecyclerViewMarginDecoration(Context context, int spanCount, int margin) {
        mMargin = ScreenUtil.dpAdapt((Activity) context, margin, 375);
        this.spanCount = spanCount;
    }

    @Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        RecyclerView.LayoutManager manager = parent.getLayoutManager();
        if (manager instanceof GridLayoutManager) {
            final GridLayoutManager gridManager = ((GridLayoutManager) manager);
            GridLayoutManager.SpanSizeLookup spanSizeLookup = gridManager.getSpanSizeLookup();
            int spanSize = spanSizeLookup.getSpanSize(parent.getChildAdapterPosition(view));
            if (spanSize == 1) {
                if (parent.getChildLayoutPosition(view) % spanCount == 0) {
                    outRect.set(mMargin, 0, mMargin / 2, 0);
                } else {
                    int lineNumber = (parent.getChildLayoutPosition(view) / spanCount) + 1;//找到行数
                    int lastItem = lineNumber * spanCount - 1; //找到这一行的最后一个item位置
                    if (parent.getChildLayoutPosition(view) == lastItem) {
                        outRect.set(mMargin / 2, 0, mMargin, 0);
                    } else {
                        outRect.set(mMargin / 2, 0, mMargin / 2, 0);
                    }
                }
            }
        }
    }
}

使用:

recyclerview.addItemDecoration(new RecyclerViewMarginDecoration(this,2,15));

猜你喜欢

转载自blog.csdn.net/csdn_lg_one/article/details/121929966