RecyclerView.ItemDecoration 源码分析

RecyclerView的是一个ViewGroup.会调用measureChild方法.

        public void measureChild(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;
            //child的宽高加上分割线的宽高
            final int widthSpec = getChildMeasureSpec(getWidth(), getWidthMode(),
                    getPaddingLeft() + getPaddingRight() + widthUsed, lp.width,
                    canScrollHorizontally());
            final int heightSpec = getChildMeasureSpec(getHeight(), getHeightMode(),
                    getPaddingTop() + getPaddingBottom() + heightUsed, lp.height,
                    canScrollVertically());
            if (shouldMeasureChild(child, widthSpec, heightSpec, lp)) {
                child.measure(widthSpec, heightSpec);
            }
        }
Rect getItemDecorInsetsForChild(View child) {
        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
        if (!lp.mInsetsDirty) {
            return lp.mDecorInsets;
        }

        if (mState.isPreLayout() && (lp.isItemChanged() || lp.isViewInvalid())) {
            // changed/invalid items should not be updated until they are rebound.
            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);
            //我重写的getItemOffsets方法.见下一段代码
            mItemDecorations.get(i).getItemOffsets(mTempRect, child, this, mState);
            insets.left += mTempRect.left;
            insets.top += mTempRect.top;
            //这里就能拿到我复写方法的的outRect.right.
            insets.right += mTempRect.right;
            insets.bottom += mTempRect.bottom;
        }
        lp.mInsetsDirty = false;
        return insets;
    }
    //比如我这样复写.
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent,           RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        //outRect的right和bottom都等于10
        outRect.right = 10;
        outRect.bottom = 10;
    }

再看RecyclerView的onDrawable方法

    @Override
    public void onDraw(Canvas c) {
        super.onDraw(c);

        final int count = mItemDecorations.size();
        for (int i = 0; i < count; i++) {
            //调用我继承ItemDecoration重写的onDraw方法.进行绘制
            mItemDecorations.get(i).onDraw(c, this, mState);
        }
    }
    @Override
    public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(canvas, parent, state);
        int childCount = parent.getChildCount();
        drawV(canvas, parent, childCount);
        drawH(canvas, parent, childCount);
    }
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 【Android 控件 RecyclerView】 概述 RecyclerView是什么 从Android 5.0...
    Rtia阅读 308,110评论 27 439
  • RecyclerView 源码分析 本文原创,转载请注明出处。欢迎关注我的 简书 ,关注我的专题 Android ...
    MeloDev阅读 13,413评论 6 49
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 175,062评论 25 709
  • 我丧命追赶 你正当逃窜 我马不停蹄 你遥不可及 你我光阴大不如前 常青藤却仍不败不散 佛云有因有果 你我确如其言无始无终
    南希故事阅读 1,443评论 4 2
  • 亲爱的宝贝, 你好!一晃四年过去了,如今你已是中班的学生了!妈妈为你感到高兴!还记得你刚出时妈妈看到你的第一...
    永远一样阅读 4,903评论 1 3