美文网首页
关于RecycleView添加分割线的问题

关于RecycleView添加分割线的问题

作者: 晓风残月酒醒 | 来源:发表于2017-06-20 17:31 被阅读0次

方法一:在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;
}
}

相关文章

网友评论

      本文标题:关于RecycleView添加分割线的问题

      本文链接:https://www.haomeiwen.com/subject/fbkaqxtx.html