RecyclerView ItemDecoration介绍

930 阅读1分钟

前言

ItemDecoration 允许应用给具体的View添加具体的图画或者layout的偏移,对于绘制View之间的分割线,视觉分组边界等等是非常有用的。

初识ItemDecoration

public abstract static class ItemDecoration {
    
    public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull State state) {
        onDraw(c, parent);
    }

    @Deprecated
    public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent) {
    }
  
    public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent,
            @NonNull State state) {
        onDrawOver(c, parent);
    }

    @Deprecated
    public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent) {
    }

    @Deprecated
    public void getItemOffsets(@NonNull Rect outRect, int itemPosition,
            @NonNull RecyclerView parent) {
        outRect.set(0, 0, 0, 0);
    }

    public void getItemOffsets(@NonNull Rect outRect, @NonNull View view,
            @NonNull RecyclerView parent, @NonNull State state) {
        getItemOffsets(outRect, ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition(),
                parent);
    }
}

排除掉弃用的方法其实真正可以让用户使用的方法就是getItemOffsetsonDrawOveronDraw 三个方法,那么这三个方法都是有什么样的作用呢?我们接下来看

getItemOffsets 中outRect作用

这个方法最重要的一个参数outRect,他能控制ItemView边界范围,也就是在给RecyclerViewItemView测量时,确定ItemView的边界范围。所以我们可以给outRect设置边界值来达到我们想要的效果,如下图所示。

onDrawOveronDraw执行的先后顺序

@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);
    }
}

@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);
    }
    ....
}

上面是RecyclerView的部分绘制代码,学过Draw流程的就应该知道执行顺序是 RecyclerView#onDraw -> ItemDecoration#onDraw -> ItemView#onDraw -> ItemDecoration#onDrawOver

所以我们可以利用他们的执行顺序,可以自定义我们想要的效果

总结

  • 当我们调用addItemDecoration()方法添加decoration的时候,RecyclerView就会调用该类的onDraw方法去绘制分隔线,也就是说:分隔线是绘制出来的。
  • RecyclerView.ItemDecoration,该类为抽象类,官方目前只提供了一个实现类DividerItemDecoration。
  • 我们可以通过onDrawOver来做到RecyclerView吸顶的效果