欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android中自定义RecyclerView.ItemDecoration

程序员文章站 2022-07-01 16:33:15
在Android应用开发中,往往显示列表都是需要用到RecyclerView的,而RecyclerView默认是没有item的分隔线的,需要调用addItemDecoration添加分隔线,你可以用它自带的DividerItemDecoration,也可以自己去继承RecyclerView.ItemDecoration来实现分隔线功能,下面我就具体来讲解下怎么自己绘制分隔线。需要重写的方法有:onDraw和getItemOffsets,还有可能重写onDrawOver。onDraw():绘制分隔...

在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

相关标签: Android应用开发