前言
RecyclerView 计划用两个章节来讲解,今天主要是以 itemDecoration 和 实现吸顶效果为主;
ItemDecoration
ItemDecoration 允许应用给具体的 View 添加具体的图画或者 Layout 的偏移,对于绘制 View 之间的分割线,视觉分组边界等等是非常有用;
当我们调用 RecyclerView 的 addItemDecoration 添加 decoration 的时候,RecyclerView 就会调用该类的 onDraw 方法去绘制分割线,也就是说分割线是绘制出来的;
RecyclerView.ItemDecoration 类是抽象类;
less
复制代码
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); } }
Android 官方只提供了一个实现类 DividerItemDecoration;我们先来简单看下它是如何实现的;
根据注释我们可以知道,DividerItemDecoration 需要结合 LinearLayoutManager 一起使用,以及它是如何创建并和 RecycerlView 如何绑定的;
我们进入构造方法看下:
可以看到,分割线其实就是一个 Drawable,我们也可以通过 setDrawable 方法自定义一个 Drawable 来定义我们的分割线;
scss
复制代码
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { if (parent.getLayoutManager() == null || mDivider == null) { return; } // 绘制的时候,根据方向,绘制不同的分割线 if (mOrientation == VERTICAL) { drawVertical(c, parent); } else { drawHorizontal(c, parent); } }
我们进入这两个方法,分别看下:
ini
复制代码
private void drawVertical(Canvas canvas, RecyclerView parent) { canvas.save(); final int left; final int right; //noinspection AndroidLintNewApi - NewApi lint fails to handle overrides. if (parent.getClipToPadding()) { left = parent.getPaddingLeft(); right = parent.getWidth() - parent.getPaddingRight(); canvas.clipRect(left, parent.getPaddingTop(), right, parent.getHeight() - parent.getPaddingBottom()); } else { left = 0; right = parent.getWidth(); } final int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { final View child = parent.getChildAt(i); parent.getDecoratedBoundsWithMargins(child, mBounds); final