ics();
res.getValue(com.android.internal.R.dimen.config_prefDialogWidth, mTmpValue, true);
int baseSize = 0;
if (mTmpValue.type == TypedValue.TYPE_DIMENSION) {
baseSize = (int)mTmpValue.getDimension(packageMetrics);
}
if (DEBUG_DIALOG) Log.v(TAG, "Window " + mView + ": baseSize=" + baseSize);
if (baseSize != 0 && desiredWindowWidth > baseSize) {
childWidthMeasureSpec = getRootMeasureSpec(baseSize, lp.width);
childHeightMeasureSpec = getRootMeasureSpec(desiredWindowHeight, lp.height);
host.measure(childWidthMeasureSpec, childHeightMeasureSpec);
if (DEBUG_DIALOG) Log.v(TAG, "Window " + mView + ": measured ("
+ host.getMeasuredWidth() + "," + host.getMeasuredHeight() + ")");
if ((host.getMeasuredWidthAndState()&View.MEASURED_STATE_TOO_SMALL) == 0) {
goodMeasure = true;
} else {
// Didn't fit in that size... try expanding a bit.
baseSize = (baseSize+desiredWindowWidth)/2;
if (DEBUG_DIALOG) Log.v(TAG, "Window " + mView + ": next baseSize="
+ baseSize);
childWidthMeasureSpec = getRootMeasureSpec(baseSize, lp.width);
host.measure(childWidthMeasureSpec, childHeightMeasureSpec);
if (DEBUG_DIALOG) Log.v(TAG, "Window " + mView + ": measured ("
+ host.getMeasuredWidth() + "," + host.getMeasuredHeight() + ")");
if ((host.getMeasuredWidthAndState()&View.MEASURED_STATE_TOO_SMALL) == 0) {
if (DEBUG_DIALOG) Log.v(TAG, "Good!");
goodMeasure = true;
}
}
}
}
? ? ? ? ? ? if (!goodMeasure) {
? ? ? ? ? ? ? ? childWidthMeasureSpec = getRootMeasureSpec(desiredWindowWidth, lp.width);
? ? ? ? ? ? ? ? childHeightMeasureSpec = getRootMeasureSpec(desiredWindowHeight, lp.height);
? ? ? ? ? ? ? ? host.measure(childWidthMeasureSpec, childHeightMeasureSpec);
? ? ? ? ? ? ? ? if (mWidth != host.getMeasuredWidth() || mHeight != host.getMeasuredHeight()) {
? ? ? ? ? ? ? ? ? ? windowSizeMayChange = true;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
这段代码基本就是在某些情况下 用特定的参数来measure , 另外一些情况下,用另外一些值来measure.
都是调用的host.measure(childWidthMeasureSpec, childHeightMeasureSpec); 只是情况不同,使用的参数不同。
计算值的这部分参见前文《 源码分析:LayoutParams的wrap_content, match_parent, 和具体值》
然后就是调用measure()方法
public final void measure(int widthMeasureSpec, int heightMeasureSpec) {
if ((mPrivateFlags & FORCE_LAYOUT) == FORCE_LAYOUT ||
widthMeasureSpec != mOldWidthMeasureSpec ||
heightMeasureSpec != mOldHeightMeasureSpec) {
// first clears the measured dimension flag
mPrivateFlags &= ~MEASURED_DIMENSION_SET;
if (ViewDebug.TRACE_HIERARCHY) {
ViewDebug.trace(this, ViewDebug.HierarchyTraceType.ON_MEASURE);
}
// measure ourselves, this should set the measured dimension flag back
onMeasure(widthMeasureSpec, heightMeasureSpec);
// flag not set, setMeasuredDimension() was not invoked, we raise
// an exception to warn the developer
if ((mPrivateFlags & MEASURED_DIMENSION_SET) != MEASURED_DIMENSION_SET) {
throw new IllegalStateException("onMeasure() did not set the"
+ " measured dimension by calling"
+ " setMeasuredDimension()");
}
mPrivateFlags |= LAYOUT_REQUIRED;
}
mOldWidthMeasureSpec = widthMeasureSpec;
mOldHeightMeasureSpec = heightMeasureSpec;
}在一些判断和标志位mPrivateFlags 赋值后,调用onMeasure() 方法。 onMeasure() 的讨论也请移步前文《 源码分析:LayoutParams的wrap_content, match_parent, 和具体值》
在方法的最后给标志位置位
mPrivateFlags |= LAYOUT_REQUIRED;
6 接着一大堆复杂的逻辑和赋值之后,调用了relayoutWindow() 这个还不太明白是怎么回事 // TODO
relayoutResult = relayoutWindow(params, viewVisibility, insetsPendi