方法一:在Adapter中获取到单个View时利用LayoutParams设置marginTop(根据position判断是否是第一个View),如此便可以利用marginTop实现分割线
方法二:在ItemView的背景中做点手脚,但是要注意第一个View、最后一个View和中间的View有些不同
方法三:
调用时这样调用:
RecycleViewDivider itemDivider = new RecycleViewDivider(getApplicationContext(), LinearLayoutManager.HORIZONTAL, BitmapHandler.dip2px(getApplicationContext(),10),
getResources().getColor(R.color.color_bg_f2f2f5));
itemDivider.setDrawLastItem(false);
mRecyclerView.addItemDecoration(itemDivider);
关于这个类,网上也有很多网友发表过文章对其进行定义,但是我建议大家直接使用RecyclerView.LayoutParams配合进行设置,而不是使用绘制的方式。采用绘制的方式会占据下一个Item头顶上一部分位置,而使用RecyclerView.LayoutParams配合进行设置则不会出现这个问题,废话少说,直接上代码:
public class RecycleViewDivider extends RecyclerView.ItemDecoration {
private Paint mPaint;
private Drawable mDivider;
private int mDividerHeight = 2;//分割线高度,默认为1px
private int mOrientation;//列表的方向:LinearLayoutManager.VERTICAL或LinearLayoutManager.HORIZONTAL
private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
private boolean mDrawLastItem;
/**
* 默认分割线:高度为2px,颜色为灰色
*
* @param context
* @param orientation 列表方向
*/
public RecycleViewDivider(Context context, int orientation) {
if (orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL) {
throw new IllegalArgumentException("请输入正确的参数!");
}
mOrientation = orientation;
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
a.recycle();
}
/**
* 自定义分割线
*
* @param context
* @param orientation 列表方向
* @param drawableId 分割线图片
*/
public RecycleViewDivider(Context context, int orientation, int drawableId) {
this(context, orientation);
mDivider = ContextCompat.getDrawable(context, drawableId);
mDividerHeight = mDivider.getIntrinsicHeight();
}
/**
* 自定义分割线
*
* @param context
* @param orientation 列表方向
* @param dividerHeight 分割线高度
* @param dividerColor 分割线颜色
*/
public RecycleViewDivider(Context context, int orientation, int dividerHeight, int dividerColor) {
this(context, orientation);
this.mDividerHeight = dividerHeight;
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(dividerColor);
mPaint.setStyle(Paint.Style.FILL);
}
/*
//获取分割线尺寸
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
outRect.set(0, 0, 0, mDividerHeight);
}*/
//绘制分割线
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
if (mOrientation == LinearLayoutManager.VERTICAL) {
drawVertical(c, parent);
} else {
drawHorizontal(c, parent);
}
}
//绘制分割线
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
if (mOrientation == LinearLayoutManager.VERTICAL) {
drawVertical(c, parent);
} else {
drawHorizontal(c, parent);
}
}
//绘制横向 item 分割线
private void drawHorizontal(Canvas canvas, RecyclerView parent) {
final int left = parent.getPaddingLeft();
final int right = parent.getMeasuredWidth() - parent.getPaddingRight();
int childSize = parent.getChildCount();
for (int i = 0; i < childSize; i++) {
final View child = parent.getChildAt(i);
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
if (!mDrawLastItem && i == childSize - 1) { //判断是否绘制最后一个item的分割线,解决最后一个分割线导致高度不一致的问题
layoutParams.bottomMargin = 0;
child.setLayoutParams(layoutParams);
break;
}
layoutParams.bottomMargin = mDividerHeight;
child.setLayoutParams(layoutParams);
// 意思就是说,要求下边伸出一部分来,用于绘制这个分割线,layoutParams.bottomMargin与View的实际高度无关
final int top = child.getBottom();
final 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);
}
}
}
//绘制纵向 item 分割线
private void drawVertical(Canvas canvas, RecyclerView parent) {
final int top = parent.getPaddingTop();
final int bottom = parent.getMeasuredHeight() - parent.getPaddingBottom();
int childSize = parent.getChildCount();
for (int i = 0; i < childSize; i++) {
final View child = parent.getChildAt(i);
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
if (!mDrawLastItem && i == childSize -1) { //判断是否绘制最后一个item的分割线,解决最后一个分割线导致宽度不一致的问题
layoutParams.rightMargin = 0;
child.setLayoutParams(layoutParams);
break;
}
layoutParams.rightMargin = mDividerHeight;
child.setLayoutParams(layoutParams);
// 意思就是说,要求右边伸出一部分来,用于绘制这个分割线,layoutParams.bottomMargin与View的实际宽度无关
final int left = child.getRight();
final 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);
}
}
}
/**
* 设置是否绘制最后一个chaildView的分割线.
* @param bool
*/
public void setDrawLastItem(boolean bool) {
mDrawLastItem = bool;
}
}