RecyclerView.ItemDecoration

来源:互联网 发布:父亲与女儿的界限知乎 编辑:程序博客网 时间:2024/06/02 12:37

RecyclerView.ItemDecoration

这个类包含三个方法 1:
•onDraw(Canvas c, RecyclerView parent, State state)
•onDrawOver(Canvas c, RecyclerView parent, State state)
•getItemOffsets(Rect outRect, View view, RecyclerView parent, State state)

getItemOffsets 中为 outRect 设置的4个方向的值,将对child的大小有影响。
outRect.set(left, top, right, bottom);

Rect getItemDecorInsetsForChild(View child) {    final LayoutParams lp = (LayoutParams) child.getLayoutParams();    if (!lp.mInsetsDirty) {        return lp.mDecorInsets;    }    final Rect insets = lp.mDecorInsets;    insets.set(0, 0, 0, 0);    final int decorCount = mItemDecorations.size();    for (int i = 0; i < decorCount; i++) {        mTempRect.set(0, 0, 0, 0);        mItemDecorations.get(i).getItemOffsets(mTempRect, child, this, mState);        insets.left += mTempRect.left;        insets.top += mTempRect.top;        insets.right += mTempRect.right;        insets.bottom += mTempRect.bottom;    }    lp.mInsetsDirty = false;    return insets;}
 public void measureChildWithMargins(View child, int widthUsed, int heightUsed) {            final LayoutParams lp = (LayoutParams) child.getLayoutParams();            final Rect insets = mRecyclerView.getItemDecorInsetsForChild(child);            widthUsed += insets.left + insets.right;            heightUsed += insets.top + insets.bottom;            final int widthSpec = getChildMeasureSpec(getWidth(), getWidthMode(),                    getPaddingLeft() + getPaddingRight() +                            lp.leftMargin + lp.rightMargin + widthUsed, lp.width,                    canScrollHorizontally());            final int heightSpec = getChildMeasureSpec(getHeight(), getHeightMode(),                    getPaddingTop() + getPaddingBottom() +                            lp.topMargin + lp.bottomMargin + heightUsed, lp.height,                    canScrollVertically());            if (shouldMeasureChild(child, widthSpec, heightSpec, lp)) {                child.measure(widthSpec, heightSpec);            }        }

在计算child的大小的时候,将outRect设置的四边减去了。

1、当RecyclerView可以水平滑动的时候
outRect设置的top,bottom将影响item的高度大小
2、当RecyclerView可以竖直滑动的时候
outRect设置的top,bottom将影响item的宽度大小

 public static int getChildMeasureSpec(int parentSize, int parentMode, int padding,                int childDimension, boolean canScroll) {            int size = Math.max(0, parentSize - padding);            int resultSize = 0;            int resultMode = 0;            if (canScroll) {                if (childDimension >= 0) {                    resultSize = childDimension;                    resultMode = MeasureSpec.EXACTLY;                } else if (childDimension == LayoutParams.MATCH_PARENT) {                    switch (parentMode) {                        case MeasureSpec.AT_MOST:                        case MeasureSpec.EXACTLY:                            resultSize = size;                            resultMode = parentMode;                            break;                        case MeasureSpec.UNSPECIFIED:                            resultSize = 0;                            resultMode = MeasureSpec.UNSPECIFIED;                            break;                    }                } else if (childDimension == LayoutParams.WRAP_CONTENT) {                    resultSize = 0;                    resultMode = MeasureSpec.UNSPECIFIED;                }            } else {                if (childDimension >= 0) {                    resultSize = childDimension;                    resultMode = MeasureSpec.EXACTLY;                } else if (childDimension == LayoutParams.MATCH_PARENT) {                    resultSize = size;                    resultMode = parentMode;                } else if (childDimension == LayoutParams.WRAP_CONTENT) {                    resultSize = size;                    if (parentMode == MeasureSpec.AT_MOST || parentMode == MeasureSpec.EXACTLY) {                        resultMode = MeasureSpec.AT_MOST;                    } else {                        resultMode = MeasureSpec.UNSPECIFIED;                    }                }            }            //noinspection WrongConstant            return MeasureSpec.makeMeasureSpec(resultSize, resultMode);        }

onDraw和onDrawOver画的区域不受outRect影响。绘制时,先执行ItemDecoration的onDraw,然后执行绘制child,最后执行ItemDecoration的onDrawOver.

原创粉丝点击