转载请注明出处:http://blog.csdn.net/crazy1235/article/details/72633385
measure - 测量
确定View的测量宽高
上面说到 performTraversals() 函数的时候,内部调用了 performMeasure()
private void performMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec) {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "measure");
try {
mView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
}
又调用了View中的 measure() 函数!
public final void measure(int widthMeasureSpec, int heightMeasureSpec) {
// 计算key值
long key = (long) widthMeasureSpec << 32 | (long) heightMeasureSpec & 0xffffffffL;
// 初始化mMeasureCache对象,用来缓存测量结果
if (mMeasureCache == null) mMeasureCache = new LongSparseLongArray(2);
final boolean forceLayout = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT;
// ...
if (forceLayout || needsLayout) {
// ...
// 尝试去查找缓存
int cacheIndex = forceLayout ? -1 : mMeasureCache.indexOfKey(key);
//没有读取到缓存或者忽略缓存时
if (cacheIndex < 0 || sIgnoreMeasureCache) {
// 测量自己
onMeasure(widthMeasureSpec, heightMeasureSpec);
mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
} else { // 读取缓存
long value = mMeasureCache.valueAt(cacheIndex);
// Casting a long to int drops the high 32 bits, no mask needed
setMeasuredDimensionRaw((int) (value >> 32), (int) value);
mPrivateFlags3 |= PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
}
// ...
mPrivateFlags |= PFLAG_LAYOUT_REQUIRED;
}
mOldWidthMeasureSpec = widthMeasureSpec;
mOldHeightMeasureSpec = heightMeasureSpec;
// 缓存
mMeasureCache.put(key, ((long) mMeasuredWidth) << 32 |
(long) mMeasuredHeight & 0xffffffffL); // suppress sign extension
}
来看 onMeasure() 函数
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec), getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}
setMeasureDimension() 函数倒是很简单!目的就是存储计算出来的测量宽高~
protected final void