该万能分割线参考自博客:RecyclerView的万能分割线_pengkv的博客-CSDN博客_android recyclerview 分割线 在他的基础上添加了距离左右边距的属性。
recyclerview最后一个条目不显示分割线且自定义分割线 - 代码先锋网
该divider可以自己定义宽高、距离左边、右边的距离,颜色等,先来看下效果:
在项目中将RecyclerViewDivider.java考入,然后再引用即可,里面有几个构造函数,可以选择合适自己的,下面举例是参数最多的那个,可以设置颜色,宽高,举例左右边界的距离:
mRecyclerView.addItemDecoration(new RecycleViewDivider(getApplicationContext(), LinearLayoutManager.VERTICAL, 20, 60, 60, getApplicationContext().getResources().getColor(R.color.colorAccent)));
下面是这个divider的所有代码,注释已经很详细了:
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
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 int mOffsetLeft = 0; //分割线偏离左边界
private int mOffsetRight = 0; //分割线偏离右边界
/**
* 默认分割线:高度为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 offsetLeft 分割线距离左边距
* @param offsetRight 分割线距离右边距
* @param dividerColor 分割线颜色
*/
public RecycleViewDivider(Context context, int orientation, int dividerHeight, int offsetLeft, int offsetRight, int dividerColor) {
this(context, orientation);
mDividerHeight = dividerHeight;
mOffsetLeft = offsetLeft;
mOffsetRight = offsetRight;
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);
if (mOrientation == LinearLayoutManager.VERTICAL) {
outRect.set(0, 0, 0, mDividerHeight);
} else {
outRect.set(0, 0, mDividerHeight, 0);
}
}
//绘制分割线
@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);
}
}
/**
* 绘制纵向列表时的分隔线 这时分隔线是横着的
* 每次 left相同,top根据child变化,right相同,bottom也变化
* @param canvas
* @param parent
*/
private void drawVertical(Canvas canvas, RecyclerView parent) {
final int left = parent.getPaddingLeft();
final int right = parent.getMeasuredWidth() - parent.getPaddingRight();
final int childSize = parent.getChildCount();
for (int i = 0; i < childSize; i++) {
final View child = parent.getChildAt(i);
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
final int top = child.getBottom() + layoutParams.bottomMargin;
final int bottom = top + mDividerHeight;
if (mDivider != null) {
mDivider.setBounds(left + mOffsetLeft, top, right - mOffsetRight, bottom);
mDivider.draw(canvas);
}
if (mPaint != null) {
canvas.drawRect(left + mOffsetLeft, top, right - mOffsetRight, bottom, mPaint);
}
}
}
/**
* 绘制横向列表时的分隔线 这时分隔线是竖着的
* l、r 变化; t、b 不变
* @param canvas
* @param parent
*/
private void drawHorizontal(Canvas canvas, RecyclerView parent) {
final int top = parent.getPaddingTop();
final int bottom = parent.getMeasuredHeight() - parent.getPaddingBottom();
final int childSize = parent.getChildCount();
for (int i = 0; i < childSize; i++) {
final View child = parent.getChildAt(i);
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
final int left = child.getRight() + layoutParams.rightMargin;
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);
}
}
}
}
当然也有更简单的方法,使用shape资源文件,不需要写java代码,适用于简单的分割线,效果如下:
但是不好的地方是,无法调整距离左右边距,或者是使用姿势不对?
使用方法:
//添加自定义分割线
DividerItemDecoration divider = new DividerItemDecoration(this,DividerItemDecoration.VERTICAL);
divider.setDrawable(ContextCompat.getDrawable(this,R.drawable.divider_mileage));
mRecyclerView.addItemDecoration(divider);
自定义的分割线的文件,在drawable/divider_mileage.xml:
上面整个项目地址:https://github.com/buder-cp/base_component_learn/tree/master/self_divider