分割线终结者---RecyclerView高度定制的“万能分割线”

此万能分割线为什么是高度定制,跟其他万能分割线有什么区别

1、其他的万能分割线仅限于横向分割线和纵向分割线

      文章介绍的万能分割线可以对每个item上下左右,360度无死角进行设置分割线(这是重要的地方)

2、其他分割线无法对每个item自定义颜色

     文章介绍的可以对没个item设定不同分割线的颜色

     下面看Demo截图  GitHub项目链接

分割线终结者---RecyclerView高度定制的“万能分割线”_第1张图片分割线终结者---RecyclerView高度定制的“万能分割线”_第2张图片分割线终结者---RecyclerView高度定制的“万能分割线”_第3张图片


对网上其他分割线的 横向和纵向都可以正常使用,重要的是对RecyclerView复杂布局下可以正常对某个item进行上下左右画线


上调用代码

    recyclerView.addItemDecoration(new UniversalItemDecoration() {
        @Override
        public Decoration getItemOffsets(int position) {

            ColorDecoration decoration = new ColorDecoration();
            //你的逻辑设置分割线
            //decoration.bottom  下分割
            //decoration.right  右分割
            //decoration.left   左分割
            //decoration.top    上分割线
            //decoration.decorationColor 分割线颜色
            return decoration;
        }
    });



非常简单,你只关系你当前item哪里要分割线就可以,不需要管里面怎么画


横向分割线示例

        recyclerView.addItemDecoration(new UniversalItemDecoration() {
            @Override
            public Decoration getItemOffsets(int position) {

                ColorDecoration decoration = new ColorDecoration();
                decoration.right = 2;
                decoration.decorationColor = Color.GREEN;
                return decoration;
            }
        });



纵向分割线示例


        recyclerView.addItemDecoration(new UniversalItemDecoration() {
            @Override
            public Decoration getItemOffsets(int position) {

                ColorDecoration decoration = new ColorDecoration();
                decoration.bottom = 2;
                decoration.decorationColor =Color.GREEN;
                return decoration;
            }
        });




横向跟纵向的差别只是right换成了bottom仅此而已


复杂布局下示例

就是第一个图的代码

        GridLayoutManager layoutManager = new GridLayoutManager(this, 6);

        //总的6列  控制每个item占据的列数
        layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {

                //设定position2-6为  两个一行的
                if (1 < position && position < 7) {
                    return 3;//3代表 当前(position)item占据3列  总6列  所以一行可以放2个
                } else if (9 < position && position < 19) {//设定position10-18为  三个一行的
                    return 2;
                } else {
                    return 6;
                }
            }
        });

        recyclerView.setLayoutManager(layoutManager);

        recyclerView.addItemDecoration(new UniversalItemDecoration() {
            @Override
            public Decoration getItemOffsets(int position) {

                ColorDecoration decoration = new ColorDecoration();

                //这里应该是你的判断逻辑  判断当前position 需要上下左右的分割线到底是多少 以及颜色

                //这是一个示例代码  这里要根据你自己的逻辑判断当前item需要上下左右的分割线到底是多少 以及颜色
                if (1 < position && position < 7) {

                    //本组占据不同的列数的 中的position
                    int index = position - 2;

                    if (isLeft(2, index)) {//是左边
                        decoration.left = 10;
                        decoration.right = 10;
                    } else if (isRight(2, index)) { //是右边
                        decoration.right = 10;
                    } else {
                        //中间
                        decoration.right = 10;
                    }

                    //前两个是第一行额外加上上边据
                    if (index < 2) {
                        decoration.top = 10;
                        decoration.bottom = 10;
                    } else {
                        decoration.bottom = 10;
                    }

                    decoration.decorationColor = Color.BLUE;

                } else if (9 < position && position < 19) {

                    int index = position - 10;

                    if (isLeft(3, index)) {
                        decoration.left = 10;
                        decoration.right = 10;
                    } else if (isRight(3, index)) {
                        decoration.right = 10;
                    } else {
                        decoration.right = 10;
                    }

                    if (index < 3) {
                        decoration.top = 10;
                        decoration.bottom = 10;
                    } else {
                        decoration.bottom = 10;
                    }

                } else {

                    //普通一个item占据6列  一行一个
                    decoration.bottom = 2;
                    decoration.decorationColor = Color.GREEN;
                }

                return decoration;
            }
        });


其中setSpanSizeLookup是系统方法,来设置当前的item占据几列


重头戏UniversalItemDecoration的代码

package com.weechan.shidexianapp.utils;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.v7.widget.RecyclerView;
import android.view.View;

import java.util.HashMap;
import java.util.Map;

import static android.plus.SM.string2Int;

/**
 * Created by yu on 2017/3/19.
 * 万能分割
 * 使用此类  item的tag会被占用  如果外部使用会造成乱
 * 外部可以使用 item.setTag(key,obj)
 */

public abstract class UniversalItemDecoration extends RecyclerView.ItemDecoration {

    private Map decorations = new HashMap<>();

    private static final String TAG = "UniversalItemDecoration";

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

        final int childSize = parent.getChildCount();
        for (int i = 0; i < childSize; i++) {

            final View child = parent.getChildAt(i);
            //获取在getItemOffsets存起来的position
            int position = string2Int(child.getTag().toString(), 0);
            Decoration decoration = decorations.get(position);

            if (decoration == null) continue;
            RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();

            //view的上下左右包括 Margin
            int bottom = child.getBottom() + layoutParams.bottomMargin;
            int left = child.getLeft() - layoutParams.leftMargin;
            int right = child.getRight() + layoutParams.rightMargin;
            int top = child.getTop() - layoutParams.topMargin;

            //下面的
            decoration.drawItemOffsets(c, left - decoration.left, bottom, right + decoration.right, bottom + decoration.bottom);
            //上面的
            decoration.drawItemOffsets(c, left - decoration.left, top - decoration.top, right + decoration.right, top);
            //左边的
            decoration.drawItemOffsets(c, left - decoration.left, top, left, bottom);
            //右边的
            decoration.drawItemOffsets(c, right, top, right + decoration.right, bottom);

        }

    }

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

        //获取position
        int position = parent.getChildAdapterPosition(view);
        view.setTag(position);

        //获取调用者返回的Decoration
        Decoration decoration = getItemOffsets(position);

        if (decoration != null) {
            //偏移量设置给item
            outRect.set(decoration.left, decoration.top, decoration.right, decoration.bottom);

        } else {
            //不要线
            decoration = null;
        }
        //存起来在onDraw用
        decorations.put(position, decoration);

    }


    /***
     * 需调用者返回分割线对象  上下左右 和颜色值
     * @param position
     * @return
     */
    public abstract Decoration getItemOffsets(int position);

    /**
     * 分割线
     */
    public abstract static class Decoration {

        public int left, right, top, bottom;

        /**
         * 根据偏移量设定的 当前的线在界面中的坐标
         *
         * @param leftZ
         * @param topZ
         * @param rightZ
         * @param bottomZ
         */
        public abstract void drawItemOffsets(Canvas c, int leftZ, int topZ, int rightZ, int bottomZ);

    }

    public static class ColorDecoration extends Decoration {

        private Paint mPaint;
        public int decorationColor = Color.BLACK;

        public ColorDecoration() {
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaint.setStyle(Paint.Style.FILL);
        }

        @Override
        public void drawItemOffsets(Canvas c, int leftZ, int topZ, int rightZ, int bottomZ) {

            mPaint.setColor(decorationColor);
            c.drawRect(leftZ, topZ, rightZ, bottomZ, mPaint);
        }

    }


    public static int string2Int(String s, int defValue) {
        try {
            return Integer.parseInt(s);
        } catch (Exception e) {
            return defValue;
        }


    }


}


核心其实也就几十行代码。

又把分割线的实现使用倒置依赖原则,可以随时扩展实现Decoration,画各种想要的线。

Github链接 




你可能感兴趣的:(android)