view的onMeasure,onLayout,onDraw源码分析

本文详细分析了Android中View的三个关键方法:onMeasure、onLayout和onDraw。onMeasure负责测量视图大小,涉及MeasureSpec的解读;onLayout确定视图位置,由ViewGroup及其子类实现;onDraw执行视图绘制,包括背景、内容和前景的绘制。文章深入探讨了这些方法在不同View和ViewGroup中的实现差异。
摘要由CSDN通过智能技术生成

1, View三部曲

在oncreate方法中加载解析完xml资源创建view对象之后,Activity中的makeVisible方法会将这些对象依次测量,确定位置并且显示在幕布上。总体的流程图如下,


重点分析onMeasure,onLayout,和onDraw方法。

1.1 onMeasure

measure是测量的意思,那么onMeasure()方法顾名思义就是用于测量视图的大小的.

1.1.1 view

首先看没有子view的测量方法.

  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
                getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
    }
public static int getDefaultSize(int size, int measureSpec) {
        int result = size;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        switch (specMode) {
        case MeasureSpec.UNSPECIFIED:
            result = size;
            break;
        case MeasureSpec.AT_MOST:
        case MeasureSpec.EXACTLY:
            result = specSize;
            break;
        }
        return result;
    }

MeasureSpec的值由specSize和specMode共同组成的,其中specSize记录的是大小(后30位),specMode记录的是规格(前2位). specMode一共有三种类型。

变量widthMeasureSpec和heightMeasureSpec都是ViewRoot的performTraversals方法中获取的,

int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
private static int getRootMeasureSpec(int windowSize, int rootDimension) {
        int measureSpec;
        switch (rootDimension) {

        case ViewGroup.LayoutParams.MATCH_PARENT:
            // Window can't resize. Force root view to be windowSize.
            measureSpec = MeasureSpec.makeMeasureSpec(windowSize, MeasureSpec.EXACTLY);
            break;
        case ViewGroup.LayoutParams.WRAP_CONTENT:
            // Window can resize. Set max size for root view.
            measureSpec = MeasureSpec.makeMeasureSpec(windowSize, MeasureSpec.AT_MOST);
            break;
        default:
            // Window wants to be an exact size. Force root view to be that size.
            measureSpec = MeasureSpec.makeMeasureSpec(rootDimension, MeasureSpec.EXACTLY);
            break;
        }
        return measureSpec;
    }

根视图总是会充满全屏的。

1.1.2 ViewGroup

既然子view都实现了o

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值