GridItemDecoration

使用方法:
1、橫向和縱向的線寬度和顏色都一樣的

 GridItemDecoration decoration = new GridItemDecoration.Builder(getActivity())
                .color(R.color.baseRed)
                .size(6)
                .isExistHead(true)
                .showHeadDivider(false)
                .showLastDivider(false)
                .build();

2、單獨(dú)設(shè)置橫向和縱向的線

GridItemDecoration decoration1 = new GridItemDecoration.Builder(getActivity())
                .verColor(R.color.baseRed)
                .horColor(R.color.baseRed)
                .verSize(1)
                .horSize(1)
                .margin(1,1)
                .isExistHead(true)
                .showHeadDivider(false)
                .showLastDivider(false)
                .build();
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.annotation.ColorRes;
import android.support.annotation.Px;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.View;

/**
 * Created by hxm on 2018/3/19.
 * 描述:
 */
public class GridItemDecoration extends RecyclerView.ItemDecoration {
    private Paint mVerPaint, mHorPaint;
    private Builder mBuilder;


    GridItemDecoration(Builder builder) {
        init(builder);
    }

    private void init(Builder builder) {
        this.mBuilder = builder;
        mVerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mVerPaint.setStyle(Paint.Style.FILL);
        mVerPaint.setColor(builder.verColor);
        mHorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mHorPaint.setStyle(Paint.Style.FILL);
        mHorPaint.setColor(builder.horColor);
    }

    private void drawHorizontal(Canvas c, RecyclerView parent) {
        int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = parent.getChildAt(i);

            //is draw head divider
            //version 1.1 update
            if (parent.getChildViewHolder(child).getItemViewType() == 1 && !mBuilder.isShowHeadDivider)
                continue;
            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            final int left = child.getLeft() - params.leftMargin;
            final int right = child.getRight() + params.rightMargin;
            final int top = child.getBottom() + params.bottomMargin;
            final int bottom = top + mBuilder.dividerHorSize;
            c.drawRect(left, top, right, bottom, mHorPaint);
        }
    }

    private void drawVertical(Canvas c, RecyclerView parent) {
        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {

            final View child = parent.getChildAt(i);

            //remove the rightmost divider
            //verion 1.1 update
            if ((parent.getChildAdapterPosition(child))% getSpanCount(parent) == 0)
                continue;
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int top = child.getTop() - params.topMargin;
            final int bottom = child.getBottom() + params.bottomMargin + mBuilder.dividerHorSize;
            final int left = child.getRight() + params.rightMargin;
            final int right = left + mBuilder.dividerVerSize;

            c.drawRect(left, top, right, bottom, mVerPaint);
        }
    }

    private int getSpanCount(RecyclerView parent) {
        // 列數(shù)
        int spanCount = -1;
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            spanCount = ((GridLayoutManager) layoutManager).getSpanCount();
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            spanCount = ((StaggeredGridLayoutManager) layoutManager)
                    .getSpanCount();
        }
        return spanCount;
    }

    private boolean isLastRaw(RecyclerView parent, int pos, int spanCount,
                              int childCount) {
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            childCount = childCount - childCount % spanCount;
            if (pos >= childCount)
                return true;
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            int orientation = ((StaggeredGridLayoutManager) layoutManager)
                    .getOrientation();
            // StaggeredGridLayoutManager 且縱向滾動(dòng)
            if (orientation == StaggeredGridLayoutManager.VERTICAL) {
                childCount = childCount - childCount % spanCount;

                if (pos >= childCount)
                    return true;
            } else
            // StaggeredGridLayoutManager 且橫向滾動(dòng)
            {

                if ((pos + 1) % spanCount == 0) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);
        drawHorizontal(c, parent);
        drawVertical(c, parent);
    }

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

        int spanCount = getSpanCount(parent);
        int childCount = parent.getAdapter().getItemCount();
        int itemPosition = ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewLayoutPosition();

        if (mBuilder.isExistHeadView)
            itemPosition -= 1;
        //set head divider offset
        //version 1.1 update
        if (mBuilder.isShowHeadDivider && itemPosition == -1)
            outRect.set(0, 0, 0, mBuilder.dividerHorSize);

        if (itemPosition < 0)
            return;

        int column = itemPosition % spanCount;
        int bottom = 0;

        int left = column * mBuilder.dividerVerSize / spanCount;
        int right = mBuilder.dividerVerSize - (column + 1) * mBuilder.dividerVerSize / spanCount;

        if (!(isLastRaw(parent, itemPosition, spanCount, childCount) && !mBuilder.isShowLastDivider))
            bottom = mBuilder.dividerHorSize;

        outRect.set(left, 0, right, bottom);
        marginOffsets(outRect, spanCount, itemPosition);
    }

    private void marginOffsets(Rect outRect, int spanCount, int itemPosition) {
        if (mBuilder.marginRight == 0 && mBuilder.marginLeft == 0)
            return;

        int itemShrink = (mBuilder.marginLeft + mBuilder.marginRight) / spanCount;
        outRect.left += (mBuilder.marginLeft - (itemPosition % spanCount) * itemShrink);

        outRect.right += ((itemPosition % spanCount) + 1) * itemShrink - mBuilder.marginLeft;
    }

    public static class Builder {
        private Context c;
        int horColor;
        int verColor;
        int dividerHorSize;
        int dividerVerSize;
        int marginLeft, marginRight;
        boolean isShowLastDivider = false;
        boolean isExistHeadView = false;
        boolean isShowHeadDivider = false;

        public Builder(Context c) {
            this.c = c;
        }

        /**
         * 設(shè)置divider的顏色
         *
         * @param color
         * @return
         */
        public Builder color(@ColorRes int color) {
            this.horColor = c.getResources().getColor(color);
            this.verColor = c.getResources().getColor(color);
            return this;
        }

        /**
         * 單獨(dú)設(shè)置橫向divider的顏色
         *
         * @param horColor
         * @return
         */
        public Builder horColor(@ColorRes int horColor) {
            this.horColor = c.getResources().getColor(horColor);
            return this;
        }

        /**
         * 單獨(dú)設(shè)置縱向divider的顏色
         *
         * @param verColor
         * @return
         */
        public Builder verColor(@ColorRes int verColor) {
            this.verColor = c.getResources().getColor(verColor);
            return this;
        }

        /**
         * 設(shè)置divider的寬度
         *
         * @param size
         * @return
         */
        public Builder size(@Px int size) {
            this.dividerHorSize = size;
            this.dividerVerSize = size;
            return this;
        }

        /**
         * 設(shè)置橫向divider的寬度
         *
         * @param horSize
         * @return
         */
        public Builder horSize(@Px int horSize) {
            this.dividerHorSize = horSize;
            return this;
        }

        /**
         * 設(shè)置縱向divider的寬度
         *
         * @param verSize
         * @return
         */
        public Builder verSize(@Px int verSize) {
            this.dividerVerSize = verSize;
            return this;
        }

        /**
         * 設(shè)置剔除HeadView的RecyclerView左右兩邊的外間距
         *
         * @param marginLeft
         * @param marginRight
         * @return
         */
        public Builder margin(@Px int marginLeft, @Px int marginRight) {
            this.marginLeft = marginLeft;
            this.marginRight = marginRight;
            return this;
        }

        /**
         * 最后一行divider是否需要顯示
         *
         * @param isShow
         * @return
         */
        public Builder showLastDivider(boolean isShow) {
            this.isShowLastDivider = isShow;
            return this;
        }

        /**
         * HeadView行divider是否需要顯示
         * Version 1.1 add
         *
         * @param isShow
         * @return
         */
        public Builder showHeadDivider(boolean isShow) {
            this.isShowHeadDivider = isShow;
            return this;
        }

        /**
         * 是否包含HeadView
         *
         * @param isExistHead
         * @return
         */
        public Builder isExistHead(boolean isExistHead) {
            this.isExistHeadView = isExistHead;
            return this;
        }

        public GridItemDecoration build() {
            return new GridItemDecoration(this);
        }

    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評(píng)論 19 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,781評(píng)論 25 709
  • 電商改變了供給和需求的交易方式 從線下到線上 從現(xiàn)金到在線支付等 大大方便了人們的交易 但它并沒有改變以錢易物的習(xí)...
    119ff67549ac閱讀 209評(píng)論 1 1
  • 現(xiàn)在大部分瀏覽器都支持flexbox布局方法。react和react-native中幾乎全部采用flex來布局。簡(jiǎn)...
    LesliePeng閱讀 1,173評(píng)論 0 2
  • 都市的繁忙與喧囂讓人疲憊,只有回到家才有放松的感覺。 ------------------ The end ---...
    荷語微光閱讀 235評(píng)論 2 2

友情鏈接更多精彩內(nèi)容