MeasureSpec类的分析以及View的工作流程

MeasureSpec是View的内部类。下面看看MeasureSpec的官方定义。


MeasureSpec把从父布局传到子布局的参数封装到布局中。每一个MeasureSpec对象代表着高或者宽。MeasureSpec由大小和模式组成,是一个32位的int值,最高2位代表着SpecMode(测量模式),最低30位代表着SpecSize(规格大小)。SpecMode有三种模式,分别是

 UNSPECIFIED //父布局没有强加子布局的大小约束,所以子布局可以有任意的大小
 EXACTLY //父布局设定了子布局的大小,子布局不能超过这个大小
 AT_MOST //子布局可以用任意具体值来设定其大小

现在看看View的工作流程
View的工作流程总结为三步

  1. measure 测量
  2. layout 布局
  3. draw 绘制
    下面,看看View的测量过程。

由源码可知,View的measure方法是final方法,子类不能修改它。最后会调用onMeasure方法。

  public final void measure(int widthMeasureSpec, int heightMeasureSpec)

下面是onMeasure方法实现

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

上面的onMeasure方法调用setMeasuredDimension方法来设置View的宽高,下面来看看getDefaultSize方法的实现。

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;
    }

可以知道,不同的测量模式有不同的测量大小。
在UNSPECIFIED模式下,传入的大小size就是返回的测量大小,其它模式都是measureSpec的specSize的大小。
下面看看获取size的方法

 protected int getSuggestedMinimumWidth() {
        return (mBackground == null) ? mMinWidth : max(mMinWidth, mBackground.getMinimumWidth());
    }
//mBackground是Drawable对象
private Drawable mBackground;

可以知道,如果View没有设置背景,那么测量的宽度就是mMinWidth ,对应属性android:minWidth的大小。如果设置了背静,就是Drawable的大小(Drawable没有设置大小默认是0)

下面,看看View的layout过程。
layout方法中会调用onLayout方法来确定View的位置,这时候的View的大小是实际展现出来的大小。

下面,看看View的绘制过程。
绘制过程

  1. 绘制背景backgroud.draw(canavs)
  2. 绘制自己(onDraw)
  3. 绘制children(dispacthDraw)
  4. 绘制装饰(onDrawScrollBars)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值