View的绘制流程分析之二 -- measure

本文详细分析了Android中View的测量过程,特别是FrameLayout的measure流程。从Activity.attach()开始,通过PhoneWindow和DecorView,探讨了ViewGroup,尤其是FrameLayout的onMeasure()方法。在测量阶段,当SpecMode为UNSPECIFIED时,View的大小由getSuggestedMinimumWidth()和getSuggestedMinimumHeight()决定;当SpecMode为AT_MOST或EXACTLY时,View的大小根据measureSpec的SpecSize确定。对于ViewGroup,如FrameLayout,会针对match_parent的子View进行二次测量,确保其尺寸正确。整个流程涉及到测量规格的计算、子View的遍历和尺寸的保存,为后续的layout和draw阶段奠定基础。
摘要由CSDN通过智能技术生成

转载请注明出处:http://blog.csdn.net/crazy1235/article/details/72633385


measure - 测量

确定View的测量宽高

上面说到 performTraversals() 函数的时候,内部调用了 performMeasure()

private void performMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec) {
        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "measure");
        try {
            mView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
        }
    }

又调用了View中的 measure() 函数!

public final void measure(int widthMeasureSpec, int heightMeasureSpec) {

        // 计算key值
        long key = (long) widthMeasureSpec << 32 | (long) heightMeasureSpec & 0xffffffffL;
        // 初始化mMeasureCache对象,用来缓存测量结果
        if (mMeasureCache == null) mMeasureCache = new LongSparseLongArray(2);

        final boolean forceLayout = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT;

        // ...

        if (forceLayout || needsLayout) {
            // ...
            // 尝试去查找缓存
            int cacheIndex = forceLayout ? -1 : mMeasureCache.indexOfKey(key);
            //没有读取到缓存或者忽略缓存时
            if (cacheIndex < 0 || sIgnoreMeasureCache) { 
                // 测量自己
                onMeasure(widthMeasureSpec, heightMeasureSpec);
                mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
            } else { // 读取缓存
                long value = mMeasureCache.valueAt(cacheIndex);
                // Casting a long to int drops the high 32 bits, no mask needed
                setMeasuredDimensionRaw((int) (value >> 32), (int) value);
                mPrivateFlags3 |= PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
            }

           // ...

            mPrivateFlags |= PFLAG_LAYOUT_REQUIRED;
        }

        mOldWidthMeasureSpec = widthMeasureSpec;
        mOldHeightMeasureSpec = heightMeasureSpec;

        // 缓存
        mMeasureCache.put(key, ((long) mMeasuredWidth) << 32 |
                (long) mMeasuredHeight & 0xffffffffL); // suppress sign extension
    }

来看 onMeasure() 函数

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec), getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
    }

setMeasureDimension() 函数倒是很简单!目的就是存储计算出来的测量宽高~

protected final void 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值