从头开始学 RecyclerView ItemDecoration 详解

Posted 匆忙拥挤repeat

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从头开始学 RecyclerView ItemDecoration 详解相关的知识,希望对你有一定的参考价值。

前言


RecyclerView.ItemDecoration,通过名字来看,它就是用来装饰Item的。
在类ListView的视图中,可能需要绘制分隔线;在类GridView的网格视图中,可能需要绘制单元格样式… 这些都可以由重写RecyclerView.ItemDecoration来进行定制。
然后调用mRecyclerView.addItemDecoration(itemDecoration); 即可

分析


看下RecyclerView.ItemDecoration的源码:

public static abstract class ItemDecoration {

    public void onDraw(Canvas c, RecyclerView parent, State state) {
        onDraw(c, parent);
    }


    public void onDrawOver(Canvas c, RecyclerView parent, State state) {
        onDrawOver(c, parent);
    }


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

这里找的是,support-v7-25.3.1的RecyclView源码,去除了已过时的方法。

关于这三方法的作用:

  • onDraw
    它在item之前绘制,就像装饰了一个item的背景,在item之前绘制

  • onDrawOver
    它在item之后绘制,就像装饰了一个item的前景,在item之后绘制

  • getItemOffsets
    指定item间的偏移量。由指定outRect的left、top、right、bottom的像素值,来偏移item。指定了偏移量后,可能会影响item的宽或高。

这三个方法的执行顺序:getItemOffsets > onDraw > onDrawOver

ItemDecoration示例


DividerItemDecoration

DividerItemDecoration,在support-v7中已经集成了。全称 android.support.v7.widget.DividerItemDecoration

通过通的注释可知,它是用于在LinearLayoutManager所管理的item之间添加分隔线。

详细代码就不贴了。值得一提的是,它里面使用了一个系统属性来指定drawable资源:private static final int[] ATTRS = new int[]{ android.R.attr.listDivider };。 一般在ListView中我们就经常使用一个xml属性:android:divider。而这里的属性android.R.attr.listDivider对应的是android:listDivider。
所以在styles.xml 中就可以定义这个属性:

<resources>
  <style ...>   
    <item name="android:listDivider">@drawable/divider_hori</item>
  </style>
</resources>

效果图:

类ListView分隔线
这条 蓝红绿颜色渐变的水平线,就是@drawable/divider_hori
 

GridDecoration

当使用GridLayoutManager时,想在每个item外绘制一个矩形框。
实现:重写RecyclerView.ItemDecoration的onDraw,绘制矩形框;重写getItemOffsets,指定item间偏移量。

@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {

    Paint paint = new Paint();
    paint.setColor(mBackColor);

    for (int i = 0, len = parent.getLayoutManager().getChildCount(); i < len; i++) {
        final View child = parent.getChildAt(i);

        int offset = 5;
        float left = child.getLeft() - offset;
        float top = child.getTop() - offset;
        float right = child.getRight() + offset;
        float bottom = child.getBottom() + offset;

        c.drawRect(left, top, right, bottom, paint);
    }
}

@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
     outRect.offset(20, 30);

     int position = parent.getChildAdapterPosition(view);
     if (position % 2 == 1) {
         outRect.offsetTo(100, 20);
     }
 }

效果图:

Grid-Item外框

图中每个item外的 淡蓝色的框,就是通过ItemDecoration#onDraw()绘制的。

示例详情见:https://github.com/aa86799/RecyclerView/tree/recycler-restart/

以上是关于从头开始学 RecyclerView ItemDecoration 详解的主要内容,如果未能解决你的问题,请参考以下文章

从头开始学 RecyclerView 添加item点击事件

从头开始学 RecyclerView 封装简化

从头开始学数据结构02

从头开始学数据结构02

从头开始学Java

学python爬虫需要从头开始学吗