天天看点

android RecyclerView (二) ItemDecoration 详解

getItemOffsets 中为 outRect 设置的4个方向的值,将被计算进所有 decoration 的尺寸中,而这个尺寸,被计入了 RecyclerView 每个 item view 的 padding 中

在 onDraw 为 divider 设置绘制范围,并绘制到 canvas 上,而这个绘制范围可以超出在 getItemOffsets 中设置的范围,但由于 decoration 是绘制在 child view 的底下,所以并不可见,但是会存在 overdraw

decoration 的 onDraw,child view 的 onDraw,decoration 的 onDrawOver,这三者是依次发生的

onDrawOver 是绘制在最上层的,所以它的绘制位置并不受限制

<code>onDraw(Canvas c, RecyclerView parent, State state)</code>

<code>onDrawOver(Canvas c, RecyclerView parent, State state)</code>

<code>getItemOffsets(Rect outRect, View view, RecyclerView parent, State state)</code>

这个outRect设置的四个值是什么意思呢?先来看看它是在哪里调用的,它在RecyclerView中唯一被调用的地方就是 <code>getItemDecorInsetsForChild(View child)</code> 函数。

可以看到,<code>getItemOffsets</code> 函数中设置的值被加到了 <code>insets</code> 变量中,并被该函数返回,那么 insets 又是啥呢?

而在 RecyclerView 的 <code>measureChild(View child, int widthUsed, int heightUsed)</code> 函数中,调用了 getItemDecorInsetsForChild,并把它算在了 child view 的 padding 中。

上面这段代码中调用 <code>getChildMeasureSpec</code> 函数的第三个参数就是 child view 的 padding,而这个参数就把 insets 的值算进去了。那么现在就可以确认了,getItemOffsets 中为 outRect 设置的4个方向的值,将被计算进所有 decoration 的尺寸中,而这个尺寸,被计入了 RecyclerView 每个 item view 的 padding 中。

这一步测试主要是对 getItemOffsets 函数传入的 outRect 参数各个值的设置,以证实上述分析的结论。

可以看到,当 left, top, right, bottom 全部设置为50时,RecyclerView 的每个 item view 各个方向的 padding 都增加了,对比各种情况,确实 getItemOffsets 中为 outRect 设置的值都将被计入 RecyclerView 每个 item view 的 padding 中。

这一步测试主要是对 onDraw 函数中对 divider 的绘制边界的设置。

有一点需要注意:decoration 的 onDraw,child view 的 onDraw,decoration 的 onDrawOver,这三者是依次发生的。而由于 onDrawOver 是绘制在最上层的,所以它的绘制位置并不受限制(当然,decoration 的 onDraw 绘制范围也不受限制,只不过不可见),所以利用 onDrawOver 可以做很多事情,例如为 RecyclerView 整体顶部绘制一个蒙层,或者为特定的 item view 绘制蒙层。这里就不单独进行测试了,请见下一节的整体效果。

实现的效果:除了最后一个 item view,底部都有一个高度为25的黑色 divider,为整个 RecyclerView 的顶部绘制了一个渐变的蒙层。效果图如下:

借鉴:https://blog.piasy.com/2016/03/26/Insight-Android-RecyclerView-ItemDecoration/

    本文转自 一点点征服   博客园博客,原文链接:http://www.cnblogs.com/ldq2016/p/5377605.html,如需转载请自行联系原作者

继续阅读