您的位置:首页 > 其它

RecyclerView ItemDecoration 学习

2017-04-13 17:17 639 查看
本次因为一直在用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上找的。我贴下我自己的效果,没有使用边缘边距。



实现代码

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: