View measurement optimization
If a view hasn't explicitly requested layout and it's asked to measure with MeasureSpec.EXACTLY in both dimensions and sizes that match its current measured size, the measure operation is a no-op. This helps out a number of ViewGroups that perform initial speculative measurements with AT_MOST or UNSPECIFIED followed by looping over child views and measuring EXACTLY to lock in the final measurement with perhaps some extra leftover space distributed. In practice this happens a fair bit, especially for views high up in the view hierarchy. This optimization allows ViewGroup measurement code to be a little cleaner in not having to keep track of this on its own. Change-Id: I88ff46a7d37aeda7a4cd16204b68cab0d051b341
This commit is contained in:
@@ -17418,17 +17418,22 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
long key = (long) widthMeasureSpec << 32 | (long) heightMeasureSpec & 0xffffffffL;
|
||||
if (mMeasureCache == null) mMeasureCache = new LongSparseLongArray(2);
|
||||
|
||||
if ((mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT ||
|
||||
widthMeasureSpec != mOldWidthMeasureSpec ||
|
||||
heightMeasureSpec != mOldHeightMeasureSpec) {
|
||||
final boolean forceLayout = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT;
|
||||
final boolean isExactly = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY &&
|
||||
MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY;
|
||||
final boolean matchingSize = isExactly &&
|
||||
getMeasuredWidth() == MeasureSpec.getSize(widthMeasureSpec) &&
|
||||
getMeasuredHeight() == MeasureSpec.getSize(heightMeasureSpec);
|
||||
if (forceLayout || !matchingSize &&
|
||||
(widthMeasureSpec != mOldWidthMeasureSpec ||
|
||||
heightMeasureSpec != mOldHeightMeasureSpec)) {
|
||||
|
||||
// first clears the measured dimension flag
|
||||
mPrivateFlags &= ~PFLAG_MEASURED_DIMENSION_SET;
|
||||
|
||||
resolveRtlPropertiesIfNeeded();
|
||||
|
||||
int cacheIndex = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT ? -1 :
|
||||
mMeasureCache.indexOfKey(key);
|
||||
int cacheIndex = forceLayout ? -1 : mMeasureCache.indexOfKey(key);
|
||||
if (cacheIndex < 0 || sIgnoreMeasureCache) {
|
||||
// measure ourselves, this should set the measured dimension flag back
|
||||
onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
|
||||
Reference in New Issue
Block a user