我们在开发中,经常会遇到RecyclerView实现分组和吸顶的需求,就如下图所示。
为了达到这样的效果,我们可以使用ItemDecoration来实现。ItemDecoration 允许应用给具体的View添加具体的图画或者layout的偏移,对于绘制View之间的分割线,视觉分组边界等等是非常有用的。
RecyclerView.ItemDecoration,该类为抽象类,官方目前只提供了一个实现类DividerItemDecoration。
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);
}
}
在ItemDecoration中,提供了onDraw、onDrawOver、getItemOffsets三个抽象方法。前两个方法均是进行绘制,但是也有不同。
在官方文档在有指出,onDraw是在itemview绘制之前,onDrawOver是在itemview绘制之后。
All ItemDecorations are drawn in the order they were added, before the item views (in onDraw() and after the items (in onDrawOver(Canvas, RecyclerView, RecyclerView.State).
下面,从绘制流程来对此进行解释。
当我们调用addItemDecoration()方法添加decoration的时候,RecyclerView会将decoration对象保存在mItemDecorations列表里面,然后调用requestLayout(),请求重新布局。
public void addItemDecoration(@NonNull ItemDecoration decor, int index) {
if (mLayout != null) {
mLayout.assertNotInLayoutOrScroll("Cannot add item decoration during a scroll or"
+ " layout");
}
if (mItemDecorations.isEmpty()) {
setWillNotDraw(false);
}
if (index < 0) {
mItemDecorations.add(decor);
} else {
mItemDecorations.add(index, decor);
}
markItemDecorInsetsDirty();
requestLayout()