当前位置: 移动技术网 > 移动技术>移动开发>Android > Android中自定义RecyclerView.ItemDecoration

Android中自定义RecyclerView.ItemDecoration

2020年07月17日  | 移动技术网移动技术  | 我要评论

在Android应用开发中,往往显示列表都是需要用到RecyclerView的,而RecyclerView默认是没有item的分隔线的,需要调用addItemDecoration添加分隔线,你可以用它自带的DividerItemDecoration,也可以自己去继承RecyclerView.ItemDecoration来实现分隔线功能,下面我就具体来讲解下怎么自己绘制分隔线。

需要重写的方法有:

onDraw和getItemOffsets,还有可能重写onDrawOver。

onDraw():绘制分隔线的具体绘制代码

onDrawOver():在item绘制完成之后,添加绘制一点东西,它和onDraw的区别在于onDraw在绘制itemView之前,而它在绘制itemView之后

getItemOffsets():设置绘制item的偏移位置,通过改变outRect的left、top、right、bottom的值来指定偏移位置,默认这4个值都为0,表示不偏移,即根据原item的宽度和高度绘制,如果不预留出位置的话,下一个item就会覆盖掉当前的分隔线的绘制。而要预留出位置,如果是垂直排列的条目,你可以这样设置outRect。

outRect.bottom = mDividerHeight;

下面看一下RecyclerView的draw()和onDraw()方法,分析过View绘制流程的就知道,View会在draw()方法里面调用onDraw(),在RecyclerView的onDraw()方法中会绘制itemDecoration的onDraw()方法和itemView的内容,绘制完成后才会绘制onDrawOver()中需要绘制的内容。
@Override
public void draw(Canvas c) {
    super.draw(c);

    final int count = mItemDecorations.size();
    for (int i = 0; i < count; i++) {
        mItemDecorations.get(i).onDrawOver(c, this, mState);
    }
    // TODO If padding is not 0 and clipChildrenToPadding is false, to draw glows properly, we
    // need find children closest to edges. Not sure if it is worth the effort.
    boolean needsInvalidate = false;
    if (mLeftGlow != null && !mLeftGlow.isFinished()) {
        final int restore = c.save();
        final int padding = mClipToPadding ? getPaddingBottom() : 0;
        c.rotate(270);
        c.translate(-getHeight() + padding, 0);
        needsInvalidate = mLeftGlow != null && mLeftGlow.draw(c);
        c.restoreToCount(restore);
    }
    if (mTopGlow != null && !mTopGlow.isFinished()) {
        final int restore = c.save();
        if (mClipToPadding) {
            c.translate(getPaddingLeft(), getPaddingTop());
        }
        needsInvalidate |= mTopGlow != null && mTopGlow.draw(c);
        c.restoreToCount(restore);
    }
    if (mRightGlow != null && !mRightGlow.isFinished()) {
        final int restore = c.save();
        final int width = getWidth();
        final int padding = mClipToPadding ? getPaddingTop() : 0;
        c.rotate(90);
        c.translate(-padding, -width);
        needsInvalidate |= mRightGlow != null && mRightGlow.draw(c);
        c.restoreToCount(restore);
    }
    if (mBottomGlow != null && !mBottomGlow.isFinished()) {
        final int restore = c.save();
        c.rotate(180);
        if (mClipToPadding) {
            c.translate(-getWidth() + getPaddingRight(), -getHeight() + getPaddingBottom());
        } else {
            c.translate(-getWidth(), -getHeight());
        }
        needsInvalidate |= mBottomGlow != null && mBottomGlow.draw(c);
        c.restoreToCount(restore);
    }

    // If some views are animating, ItemDecorators are likely to move/change with them.
    // Invalidate RecyclerView to re-draw decorators. This is still efficient because children's
    // display lists are not invalidated.
    if (!needsInvalidate && mItemAnimator != null && mItemDecorations.size() > 0
            && mItemAnimator.isRunning()) {
        needsInvalidate = true;
    }

    if (needsInvalidate) {
        ViewCompat.postInvalidateOnAnimation(this);
    }
}
@Override
public void onDraw(Canvas c) {
    super.onDraw(c);

    final int count = mItemDecorations.size();
    for (int i = 0; i < count; i++) {
        mItemDecorations.get(i).onDraw(c, this, mState);
    }
}

 

本文地址:https://blog.csdn.net/a_lwh____/article/details/107378053

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网