练习RecyclerView添加分割线

RecyclerView需要手动添加分割线,之前每次都是把代码复制粘贴上去了。刚刚练习了一下如何添加竖线分割线和横向间隔线以及双向添加分割线。现在记录一下,但是绘制图片部分需要修改,具体该怎么弄我要找一下资料。先放上普通单色线。




import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.View;

import static android.graphics.Paint.ANTI_ALIAS_FLAG;

/**
 * <pre>
 *  名称:RecyclerViewItemDecoration
 *  作用:RecyclerView分割线
 *  描述:
 *  作者:pczhu
 *  创建时间: 2017/6/14 上午11:49
 *  版本:V1.0
 *  修改历史:
 *  </pre>
 */

public class RecyclerViewItemDecoration extends RecyclerView.ItemDecoration {

    private Context mContext;
    /**
     * <pre>
     *      方向参数,默认纵向
     *      0x10000000:Vertical纵向
     *      0x20000000:Horizontal横向
     * </pre>
     */
    private int mOrientation = 0x10000000;
    /**
     * <pre>
     *      横向
     * </pre>
     */
    public static final int Horizontal = 0x10000000;
    /**
     * <pre>
     *      纵向
     * </pre>
     */
    public static final int Vertical = 0x20000000;
    private Paint mPaint;
    /**
     * <pre>
     *      颜色参数:分割线颜色
     *      默认颜色:#eeeeee
     * </pre>
     */
    private int mDividerColor =  Color.parseColor("#000000");
    /**
     * <pre>
     *      分割线高度
     *          默认2sp
     * </pre>
     */
    private int mDividerHeight = 2;
    /**
     * <pre>
     *     分割线宽度
     *          默认2sp
     * </pre>
     */
    private int mDividerWidth = 2;
    private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
    private Drawable mDivider;

    private void setDividerColor(int mDividerColor) {
        this.mDividerColor = mDividerColor;
    }

    private void setDividerHeight(int mDividerHeight) {
        this.mDividerHeight = dip2px(mDividerHeight);
    }

    private void setDividerWidth(int mDividerWidth) {
        this.mDividerWidth = dip2px(mDividerWidth);
    }

    private void setDivider(Drawable mDivider) {
        this.mDivider = mDivider;
    }

    public void setOrientation(int mOrientation) {
        this.mOrientation = mOrientation;
    }

    /**
     * 默认分割线:高度为2px,颜色为灰色
     *
     * @param context
     * @param orientation 列表方向
     */
    public RecyclerViewItemDecoration(Context context, int orientation) {
        this.mContext = context;
        if ((orientation & LinearLayoutManager.VERTICAL) == 1
                && (orientation & LinearLayoutManager.HORIZONTAL) == 1) {
            throw new IllegalArgumentException("请输入正确的参数!");
        }
        mOrientation = orientation;

        final TypedArray a = context.obtainStyledAttributes(ATTRS);
        mDivider = a.getDrawable(0);
        a.recycle();
        if(mDivider==null){
            initPaint();
        }
    }


    /**
     * 初始化画笔
     */
    private void initPaint() {
        mPaint = new Paint(ANTI_ALIAS_FLAG);
        mPaint.setColor(mDividerColor);
    }
    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);
        if(getLayoutManagerType(parent) != 2){

            if(mOrientation == (Horizontal|Vertical)){
                drawDividerBothLine(c,parent);
            }else if(mOrientation == Vertical){
                drawDividerVertical(c, parent);
            }else {
                drawDividerHorizontal(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);
        //特殊的item间距
        if(getLayoutManagerType(parent) == 2){//流 折半 每个偏移一半的值 相邻就会偏移一个
            outRect.left = mDividerWidth/2;
            outRect.right = mDividerWidth/2;
            outRect.bottom = mDividerHeight/2;
            outRect.top = mDividerHeight/2;

        }else {//其他分割线
            if(mOrientation == (Horizontal|Vertical)){
                if((parent.getChildAdapterPosition(view)+1)%spanCount == 0){
                    outRect.set(0,0,0,mDividerHeight);
                }else {
                    outRect.set(0,0,mDividerWidth,mDividerHeight);
                }
            }else if(mOrientation == Vertical){
                outRect.set(0,0,0,mDividerHeight);
            }else if(mOrientation == Horizontal){
                outRect.set(0,0,mDividerHeight,0);
            }

        }
    }

    /**
     * 划竖排列表的分割线
     * @param c
     * @param parent
     */
    private void drawDividerVertical(Canvas c,RecyclerView parent){
        int leftParent = parent.getPaddingLeft();
        int rightParent = parent.getWidth()-parent.getPaddingRight();

        int childCount = parent.getChildCount();
        for(int i = 0;i < childCount ; i++){
            View mChildView = parent.getChildAt(i);
            RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) mChildView.getLayoutParams();

            int left = leftParent+layoutParams.leftMargin;
            int right = rightParent-layoutParams.rightMargin;
            int top = mChildView.getBottom()+layoutParams.bottomMargin;
            if (mDivider != null) {
                mDivider.setBounds(left, top, right, top+mDividerHeight);
                mDivider.draw(c);
            }
            if (mPaint != null) {
//                Log.i("定点", left + ":" + top + ":" + right + ":" + (top + mDividerHeight));
                Rect rect = new Rect(left, top, right, (top + mDividerHeight));
                c.drawRect(rect, mPaint);
            }
        }
    }

    /**
     * 划横排列表间隔线
     * @param canvas
     * @param parent
     */
    private void drawDividerHorizontal(Canvas canvas, RecyclerView parent) {
        int top = parent.getPaddingTop();
        int bottom = parent.getMeasuredHeight() - parent.getPaddingBottom();
        int childSize = parent.getChildCount();
        for (int i = 0; i < childSize; i++) {
            View mChildView = parent.getChildAt(i);
            RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) mChildView.getLayoutParams();
            int left = mChildView.getRight() + layoutParams.rightMargin;
            int right = left + mDividerHeight;

            if (mDivider != null) {
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(canvas);

            }
            if (mPaint != null) {
                canvas.drawRect(left, top, right, bottom, mPaint);
            }
        }
    }

    /**
     * 同时画横向间隔线 竖向分割线
     * @param canvas
     * @param parent
     */
    private void drawDividerBothLine(Canvas canvas, RecyclerView parent) {
        int spanCount = getSpanCount(parent);
        int childSize = parent.getChildCount();
        for (int i = 0; i < childSize; i++) {
            View mChildView = parent.getChildAt(i);
            RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) mChildView.getLayoutParams();

            if((i+1) % spanCount == 0){//划竖向行分界线

                int left = parent.getPaddingLeft()+layoutParams.leftMargin;
                int right = parent.getMeasuredWidth()-parent.getPaddingRight()-layoutParams.rightMargin;
                int top = mChildView.getBottom()+layoutParams.bottomMargin;
                int bottom = top+mDividerHeight;
                if (mDivider != null) {
                    mDivider.setBounds(left, top, right, bottom);
                    mDivider.draw(canvas);
                }
                if (mPaint != null) {
                    canvas.drawRect(left, top, right, bottom, mPaint);
                }
            }else{//划横向item间线

                int left = mChildView.getRight() + layoutParams.rightMargin;
                int right = left + mDividerWidth;
                int top = mChildView.getTop()-layoutParams.topMargin;
                int bottom = mChildView.getTop()+mChildView.getMeasuredHeight()+layoutParams.bottomMargin;
                if (mDivider != null) {
                    mDivider.setBounds(left, top, right, bottom);
                    mDivider.draw(canvas);
                }
                if (mPaint != null) {
                    canvas.drawRect(left, top, right, bottom, mPaint);
                }
            }
        }
    }
    /**
     * 获取列数
     *
     * @param parent
     * @return
     */
    private int getSpanCount(RecyclerView parent) {
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        int spanCount = -1;
        switch (getLayoutManagerType(parent)){
            case 1:
                spanCount = ((GridLayoutManager) layoutManager).getSpanCount();
                break;
            case 2:
                spanCount = ((StaggeredGridLayoutManager) layoutManager)
                        .getSpanCount();
                break;

        }
        return spanCount;
    }

    /**
     * 返回manager类型
     * @param parent
     * @return
     */
    private int getLayoutManagerType(RecyclerView parent){
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            return 1;
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            return 2;
        } else if (layoutManager instanceof LinearLayoutManager){
            return 3;
        }else{
            return -1;
        }
    }
    public static class Builder{
        private Context mContext;
        RecyclerViewItemDecoration recyclerViewItemDecoration;
        /**
         * <pre>
         *      方向参数,默认纵向
         *      0x10000000:Vertical纵向
         *      0x20000000:Horizontal横向
         * </pre>
         */
        private int mOrientation = 0x10000000;
        /**
         * <pre>
         *      颜色参数:分割线颜色
         *      默认颜色:#eeeeee
         * </pre>
         */
        private int mDividerColor =  Color.parseColor("#000000");
        /**
         * <pre>
         *      分割线高度
         *          默认2sp
         * </pre>
         */
        private int mDividerHeight = 2;
        /**
         * <pre>
         *     分割线宽度
         *          默认2sp
         * </pre>
         */
        private int mDividerWidth = 2;
        /**
         * <pre>
         *     作为分割线的图片资源
         * </pre>
         */
        private Drawable mDivider;

        public Builder(Context mContext) {
            this.mContext = mContext;
            recyclerViewItemDecoration = new RecyclerViewItemDecoration(mContext,mOrientation);
        }

        /**
         * 设置方向
         * @param mOrientation
         * @return
         */
        public Builder setOrientation(int mOrientation) {
            this.mOrientation = mOrientation;
            recyclerViewItemDecoration.setOrientation(mOrientation);
            return this;
        }

        /**
         * 设置颜色
         * @param mDividerColor
         * @return
         */
        public Builder setDividerColor(int mDividerColor) {
            this.mDividerColor = mDividerColor;
            recyclerViewItemDecoration.setDividerColor(mDividerColor);
            return this;
        }

        /**
         * 设置纵向分割线高度
         * @param mDividerHeight dp单位
         * @return
         */
        public Builder setDividerHeight(int mDividerHeight) {
            this.mDividerHeight = mDividerHeight;
            recyclerViewItemDecoration.setDividerHeight(mDividerHeight);
            return this;
        }

        /**
         * 设置分割线宽度
         * @param mDividerWidth dp单位
         * @return
         */
        public Builder setDividerWidth(int mDividerWidth) {
            this.mDividerWidth = mDividerWidth;
            recyclerViewItemDecoration.setDividerWidth(mDividerWidth);
            return this;
        }

        /**
         * 设置分割线图片
         * @param mDivider
         * @return
         */
        public Builder setDivider(Drawable mDivider) {
            this.mDivider = mDivider;
            recyclerViewItemDecoration.setDivider(mDivider);
            return this;
        }
        public RecyclerViewItemDecoration build(){
            return recyclerViewItemDecoration;

        }
    }


    public int dip2px(float dpValue) {
        if(mContext == null){
            return 2;
        }
        final float scale = mContext.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
     */
    public int px2dip(float pxValue) {
        final float scale = mContext.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }
}


        mRecyclerView.addItemDecoration(new RecyclerViewItemDecoration.Builder(this)
                .setOrientation(RecyclerViewItemDecoration.Vertical|RecyclerViewItemDecoration.Horizontal)
                .setDividerHeight(4)
                .setDividerWidth(4)
//                .setDivider(getResources().getDrawable(R.mipmap.abc))
                .setDividerColor(Color.parseColor("#eebbdd"))
                .build());
Markdown

Markdown
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容