关于measure

子View的MeasureSpec的值是由(子View的布局参数(LayoutParams)和父容器的MeasureSpec值)计算得来的,具体逻辑

/* 
 * @param spec  父View的详细测量值
@param padding  View当前尺寸的内边距和外边距     
 * @param childDimension  子视图的布局参数
 * @return a MeasureSpec integer for the child
 */
public static int getChildMeasureSpec(int spec, int padding, int childDimension) 

根据View的类型measure过程主要分为两种情况
(1)单一View的measure过程
1. measure过程:该方法被final修饰,不可以被覆写
基本测量逻辑的判断(先判断是否是强制测量、测量模式改变了没有,再判断是否强制测量、忽略缓存)
if (是否强制测量  ||  是否需要重新测量(测量模式有没有改变)) {
if (mMeasureCache缓存中没有取到值 || 是否忽略缓存) {
    onMeasure();
}
}
2. onMeasure()过程:
setMeasureDimension()
getDefaultSize()
getSuggestedMinimumWidth()
因此:在自定义控件时候,如果没有重写onMeasure方法,同时给控件设置wrap_content属性时,控件默认会显示match_parent效果。
其中:
mMeasureCache中存储通过传入的widthMeasureSpec和heightMeasureSpec计算得出的key值信息,即view的信息。
long key = (long) widthMeasureSpec << 32 | (long) heightMeasureSpec & 0xffffffffL;
mPrivateFlags用于记录了View的各种状态位。
(2)ViewGroup的measure过程
1. measureChildren()
for (遍历ViewGroup中的所有子View) {
if (View不是GONE状态) {
measureChild()
}
}
2. measureChild()
measureSpec = 通过getChildMeasureSpec()方法获取到当前Child的MeasureSpec的值
measure(measureSpec);
3.  getChildMeasureSpec()  根据父布局的MeasureSpec和当前View的尺寸决定当前View的MeasureSpec
4.  measure()

单一View的measure过程与ViewGroup过程最大的不同:单一View对onMeasure()具有统一的实现,而ViewGroup没有

若LinearLayout的子View设置了weight,会进行两次measure计算,会比较耗时,所有当LinearLayout的子View需要使用weight的时候,最好替换成RelativeLayout布局
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值