美文网首页
关于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