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,如需轉載請自行聯系原作者