android measure类型,Android系统_View.measure解析

图文概览

View测量流程

measure

性质:final方法,View测量初始方法

作用:基本逻辑计算,是否重新测量,调用onMeasure,缓存测量规格

onMeasure

性质:测量方法,子类可复写实现自己的测量方式

作用:进行测量规格计算,调用getDefaultSize和setMeasureDimension

getDefaultSize

作用:根据View的测量规格计算宽/高值

setMeasureDimension

作用:存储测量后的宽/高值

ViewGroup测量大概流程

c7859e02cf25

源码分析

View.measure流程

// view measure入口, final类型

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

// 是否需要再次计算等计算

...

if (cacheIndex < 0 || sIgnoreMeasureCache) {

// 计算视图大小

onMeasure(widthMeasureSpec, heightMeasureSpec);

mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;

}else {

setMeasuredDimensionRaw((int) (value >> 32), (int) value);

}

}

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

// 存储测量后的View宽 / 高

setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),

getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));

}

// View的宽度为mMinWidth和mBackground.getMinimumWidth()中的最大值,高度类似

protected int getSuggestedMinimumWidth() {

return (mBackground == null) ? mMinWidth : max(mMinWidth,mBackground.getMinimumWidth());

}

// 根据View宽/高的测量规格计算View的宽/高值

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;

// 模式为AT_MOST,EXACTLY时,使用View测量后的宽/高值 = measureSpec中的Size

case MeasureSpec.AT_MOST:

case MeasureSpec.AT_MOST:

case MeasureSpec.EXACTLY:

result = specSize;

break;

}

return result;

}

// 存储测量后的View宽 / 高

protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) {

boolean optical = isLayoutModeOptical(this);

if (optical != isLayoutModeOptical(mParent)) {

Insets insets = getOpticalInsets();

int opticalWidth = insets.left + insets.right;

int opticalHeight = insets.top + insets.bottom;

measuredWidth += optical ? opticalWidth : -opticalWidth;

measuredHeight += optical ? opticalHeight : -opticalHeight;

}

setMeasuredDimensionRaw(measuredWidth, measuredHeight);

}

private void setMeasuredDimensionRaw(int measuredWidth, int measuredHeight) {

mMeasuredWidth = measuredWidth;

mMeasuredHeight = measuredHeight;

mPrivateFlags |= PFLAG_MEASURED_DIMENSION_SET;

}

ViewGroup.onMeasure

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

// ViewGroup 继承类,大体都要充写次方法,大体模式如下

// 遍历子View,对子控件一一measure

for(int i=0;i

measureChild(child, widthMeasureSpec, heightMeasureSpec)

}

// 合并所有子控件大小,计算出父控件宽高测量规格

mergeChildSpec() ; // 也有可能与第一步同时计算

// 设置父控件的宽/高值

setMeasuredDimension(widthMeasure, heightMeasure);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值