RecyclerView ItemDecoration 学习

来源:互联网 发布:御剑扫描器 源码 编辑:程序博客网 时间:2024/05/17 04:08

本次因为一直在用RecyclerView LinearLayoutManager对应的decoration,目前处理GridLayout时由于要处理左右侧的item的边距和蹭的Item边距不同,就回顾一下RecyclerView 对ItemDecoration的学习。

由于不是ListView和GridView,RecyclerView把这个称为Item的装饰,所以分隔线的处理就交给ItemDecoration来处理。
RecyclerView设置ItemDecoration调用如下方法:

recyclerView.addItemDecoration()

ItemDecoration类主要是三个方法:

public void onDraw(Canvas c, RecyclerView parent, State state)public void onDrawOver(Canvas c, RecyclerView parent, State state)public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state)
  • getItemOffsets 中为 outRect 设置的4个方向的值,将被计算进所有 decoration的尺寸中,而这个尺寸,被计入了 RecyclerView 每个 item view 的 padding 中
  • 在 onDraw 为 divider 设置绘制范围,并绘制到 canvas 上,而这个绘制范围可以超出在 getItemOffsets 中设置的范围,但由于 decoration 是绘制在 child view 的底下,所以并不可见,但是会存在overdraw
  • decoration 的 onDraw,child view 的 onDraw,decoration 的 onDrawOver,这三者是依次发生的
  • onDrawOver 是绘制在最上层的,所以它的绘制位置并不受限制

所以ItemDecoration 不仅仅限制于作Divider,还可以做一些Item的装饰,比如一些电商的热卖标识,提醒标记都可以用ItemDecoration来做,关于StickyHeader也可以用ItemDecoration做。

关于分组就是与外部交换数据确实group位置,并在group组内第一个数据上方添加decoration。具体这一块可以直接参考RecyclerView之ItemDecoration由浅入深。讲得很清楚,还把stickyHeader实现了。

后面实质上是数学的计算来设置每个item的left, top, right, bottom的具体数值。由于麻烦是Grid的item的边距,一般都是每个item的上下和左右边距是一样的,非常对称,边缘部分没有边距,正好项目以上有这个itemdecoration,所以共享出来,应该是之前网上找好,就是这个文章里的 Android RecyclerView 间距全适配,不过我是在github上找的。我贴下我自己的效果,没有使用边缘边距。

grid

实现代码

    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {        int position = parent.getChildAdapterPosition(view); // item position        int column = position % spanCount; // item column        if (includeEdge) {            outRect.left = spacing - column * spacing / spanCount; // spacing - column * ((1f / spanCount) * spacing)            outRect.right = (column + 1) * spacing / spanCount; // (column + 1) * ((1f / spanCount) * spacing)            if (position < spanCount) { // top edge                outRect.top = spacing;            }            outRect.bottom = spacing; // item bottom        } else {            outRect.left = column * spacing / spanCount; // column * ((1f / spanCount) * spacing)            outRect.right = spacing - (column + 1) * spacing / spanCount; // spacing - (column + 1) * ((1f /    spanCount) * spacing)            if (position >= spanCount) {                outRect.top = spacing; // item top            }        }    }

上面代码计算还是非常巧妙的,代码少体现的则是边距和位置的关系计算各种分多少spacing.

以下是参考资料,已经讲得非常清楚,效果如下。

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

参考连接
RecyclerView 自定义 ItemDecoration
bignerdranch simple item decoration
RecyclerView之ItemDecoration由浅入深
stackoverflow issue
RecyclerView定制:通用ItemDecoration及全展开RecyclerView的实现
深入理解 RecyclerView 系列之一:ItemDecoration


0 0