ItemDecoration

getItemOffsets

为了给绘制 Decoration 腾出绘制区域,RecyclerView 通过调用 ItemDecoration 的 getItemOffsets,获取需要的绘制区域尺寸,保存到 RecyclerView.LayoutParams 的 mDecorInsets 变量里。

RecyclerView measure 和 layout 过程中会考虑到 mDecorInsets,也就是说除了 Padding,Margin 之外,RecyclerView 还增加了 mDecorInsets 进行布局。mDecorInsets 的作用Margin 比较相似。

onDraw,onDrawOver

onDraw 和 onDrawOver 都是绘制 Decoration,区别在于,onDraw 在 RecyclerView 绘制 Children 之前,onDrawOver 在 RecyclerView 绘制 Children 之后。

以 DividerItemDecoration 为例分析

getItemOffsets 根据方向,为 outRect 的 bottom 或者 left 设置了 mDivider 的高度或宽度。

getItemOffsets

onDraw 过程,根据方向,调用 drawVertical 或者 drawHorizontal。

onDraw

以 drawVertical 为例进行分析。

drawVertical

先调用 RecyclerView 的 getDecorationBoundsWithMargins 获取到一个 Rect mBounds。

根据 bottom 和 mDivider 的 height,得到 Decoration 绘制区域。

getDecoratedBoundsWithMaginsInt

RecyclerView 的 getDecorationBoundsWithMargins 其实调用的是 RecyclerView 的 static 方法 getDecoratedBoundsWithMarginsInt。可以看到,outBounds 根据 View 的位置参数,margin 以及 insets 生成。这个 insets 与前面 getItemOffset 获取到的 Rect 属性相同。

自己定制

综上而言,要定制自己的 ItemDecoration 其实非常简单,只需要 override getItemOffsets 函数, 为 View 的上下左右腾出绘制区域。然后在 onDraw 或者 onDrawOver 时,通过 RecyclerView.LayoutParams 和 View 的位置信息,计算绘制区域,绘制 Decoration 即可。

获取 View 布局参数等过程可以参考 DividerItemDecoration。

思考

RecyclerView 添加 ItemDecoration 的方法是 addItemDecoration 而不是 setItemDecoration,说明一个 RecyclerView 可以有多个 ItemDecoration。一般来说,一个 Decoration 已经够用了。但当有多个 ItemDecoration 时,它们的 ItemOffsets 是重叠(最终大小由最大的 ItemOffset 决定)?还是相加呢?

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 10 国庆长假陈米粒没有听妈妈的话把朱生豪带回家,而是和徐婷婷去重庆玩了一趟,说是要陪徐婷婷散心,可实际上她又何尝...
    余思月阅读 1,681评论 0 2
  • [概念基础]黑客如何工作的白帽子的法律约束 [技术基础]漏洞扫描工具AWVS ***网络安全审计工具Nm...
    虾想家阅读 553评论 0 0
  • 体重:95kg 碳水化合物:81g 蛋白质:285g 脂肪:20g 低碳日(81g) 6:15 起床6:45 快速...
    SYF_LEO阅读 195评论 0 0
  • 爱情总是在不经意的时候来临 刻意的寻找 也许永远也找不到 不经意间 你却会遇到那个你苦苦等待的人 不经意的相遇 不...
    美文小屋阅读 772评论 0 0