1、其他的万能分割线仅限于横向分割线和纵向分割线
文章介绍的万能分割线可以对每个item上下左右,360度无死角进行设置分割线(这是重要的地方)
2、其他分割线无法对每个item自定义颜色
文章介绍的可以对没个item设定不同分割线的颜色
下面看Demo截图 GitHub项目链接
对网上其他分割线的 横向和纵向都可以正常使用,重要的是对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;
}
});
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占据几列
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链接