、、、
}
3、FrameLayout的onMeasure方法
注释1处先求出子view个数;
在注释2处表示循环遍历每一个子view然后执行measureChildWithMargins;
测量完所有子view之后在注释3处设置自身的尺寸;
注释4和注释5表示会对所有设置MatchParent属性的子view重新measure,因为MatchParent属性比较特殊,刚开始并不知道父view的尺寸,所以需要重新测量;
我们继续看一下注释2处是怎么测量子view的,FrameLayout并没有measureChildWithMargins方法,而是在父类ViewGroup中定义的,我们接着看一下ViewGroup的measureChildWithMargins方法;
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int count = getChildCount(); //1
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (mMeasureAllChildren || child.getVisibility() != GONE) {
measureChildWithMargins(child, widthMeasureSpec, 0,heightMeasureSpec,0); //2
}
}
setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
resolveSizeAndState(maxHeight, heightMeasureSpec,
childState << MEASURED_HEIGHT_STATE_SHIFT)); //3
count = mMatchParentChildren.size(); //4
if (count > 1) {
for (int i = 0; i < count; i++) {
final View child = mMatchParentChildren.get(i);
final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
、、、
child.measure(childWidthMeasureSpec, childHeightMeasureSpec); //5
}
}
}
4、ViewGroup的measureChildWithMargins方法
注释1处先求出子view的LayoutParams布局参数;
然后在注释2和注释3处通过父view的MeasureSpec和子view的布局参数确定子view的MeasureSpec;
最后在注释4处又调用了child.measure(childWidthMeasureSpec, childHeightMeasureSpec);这样又会递归调用到View的measure方法,在measure方法中又会调用onMeasure方法,如果这个子view是一个viewgroup类型的,则又会递归调用到该viewgroup的onMeasure方法;直到递归调用到最下层view时,则会调用到View的onMeasure方法;
protected void measureChildWithMargins(View child,
int parentWidthMeasureSpec, int widthUsed,
int parentHeightMeasureSpec, int heightUsed) {
final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); //1
final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,
mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin
- widthUsed, lp.width); //2
final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,
mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin - heightUsed, lp.height); //3
child.measure(childWidthMeasureSpec, childHeightMeasureSpec); //4
}
5、View的onMeasure方法
注释1处的setMeasuredDimension方法设置自身的尺寸,通过getDefaultSize获取尺寸;
注释3和注释4将mMeasuredWidth和mMeasuredHeight赋值为我们测量后的值;因此measure流程结束我们就可以通过getMeasuredWidth和hgetMeasuredeight获取尺寸了,比如我们在onLayout方法中就会可以调用;
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), width