RecyclerView ItemDecoration 学习

本次因为一直在用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


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值