private static boolean sUseBrokenMakeMeasureSpec = false;
/**
+ * Always return a size of 0 for MeasureSpec values with a mode of UNSPECIFIED
+ */
+ static boolean sUseZeroUnspecifiedMeasureSpec = false;
+
+ /**
* Ignore any optimizations using the measure cache.
*/
private static boolean sIgnoreMeasureCache = false;
Canvas.sCompatibilityRestore = targetSdkVersion < MNC;
+ // In MNC and newer, our widgets can pass a "hint" value in the size
+ // for UNSPECIFIED MeasureSpecs. This lets child views of scrolling containers
+ // know what the expected parent size is going to be, so e.g. list items can size
+ // themselves at 1/3 the size of their container. It breaks older apps though,
+ // specifically apps that use some popular open source libraries.
+ sUseZeroUnspecifiedMeasureSpec = targetSdkVersion < MNC;
+
sCompatibilityDone = true;
}
}
}
/**
+ * Like {@link #makeMeasureSpec(int, int)}, but any spec with a mode of UNSPECIFIED
+ * will automatically get a size of 0. Older apps expect this.
+ *
+ * @hide internal use only for compatibility with system widgets and older apps
+ */
+ public static int makeSafeMeasureSpec(int size, int mode) {
+ if (sUseZeroUnspecifiedMeasureSpec && mode == UNSPECIFIED) {
+ return 0;
+ }
+ return makeMeasureSpec(size, mode);
+ }
+
+ /**
* Extracts the mode from the supplied measure specification.
*
* @param measureSpec the measure specification to extract the mode from
} else if (childDimension == LayoutParams.MATCH_PARENT) {
// Child wants to be our size... find out how big it should
// be
- resultSize = size;
+ resultSize = View.sUseZeroUnspecifiedMeasureSpec ? 0 : size;
resultMode = MeasureSpec.UNSPECIFIED;
} else if (childDimension == LayoutParams.WRAP_CONTENT) {
// Child wants to determine its own size.... find out how
// big it should be
- resultSize = size;
+ resultSize = View.sUseZeroUnspecifiedMeasureSpec ? 0 : size;
resultMode = MeasureSpec.UNSPECIFIED;
}
break;
final int adjMaxWidth = maxWidth - marginLeft - marginRight;
final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(adjMaxWidth, MeasureSpec.AT_MOST);
- final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(container.height(),
+ final int heightMeasureSpec = MeasureSpec.makeSafeMeasureSpec(container.height(),
MeasureSpec.UNSPECIFIED);
view.measure(widthMeasureSpec, heightMeasureSpec);
final int containerWidth = container.width();
final int adjMaxWidth = containerWidth - marginLeft - marginRight;
final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(adjMaxWidth, MeasureSpec.AT_MOST);
- final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(container.height(),
+ final int heightMeasureSpec = MeasureSpec.makeSafeMeasureSpec(container.height(),
MeasureSpec.UNSPECIFIED);
preview.measure(widthMeasureSpec, heightMeasureSpec);
final Rect container = mContainerRect;
final int maxWidth = container.width();
final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.AT_MOST);
- final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(container.height(),
+ final int heightMeasureSpec = MeasureSpec.makeSafeMeasureSpec(container.height(),
MeasureSpec.UNSPECIFIED);
track.measure(widthMeasureSpec, heightMeasureSpec);
p.forceAdd = true;
int childHeightSpec = getChildMeasureSpec(
- MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec),
+ MeasureSpec.makeSafeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec),
MeasureSpec.UNSPECIFIED), 0, p.height);
int childWidthSpec = getChildMeasureSpec(
MeasureSpec.makeMeasureSpec(mColumnWidth, MeasureSpec.EXACTLY), 0, p.width);
// use as much space as it wants because we can shrink things
// later (and re-measure).
if (baselineAligned) {
- final int freeWidthSpec = MeasureSpec.makeMeasureSpec(
+ final int freeWidthSpec = MeasureSpec.makeSafeMeasureSpec(
MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.UNSPECIFIED);
- final int freeHeightSpec = MeasureSpec.makeMeasureSpec(
+ final int freeHeightSpec = MeasureSpec.makeSafeMeasureSpec(
MeasureSpec.getSize(heightMeasureSpec), MeasureSpec.UNSPECIFIED);
child.measure(freeWidthSpec, freeHeightSpec);
} else {
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
} else {
- childHeightSpec = MeasureSpec.makeMeasureSpec(heightHint, MeasureSpec.UNSPECIFIED);
+ childHeightSpec = MeasureSpec.makeSafeMeasureSpec(heightHint, MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec, childHeightSpec);
}
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
} else {
- childHeightSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight(),
+ childHeightSpec = MeasureSpec.makeSafeMeasureSpec(getMeasuredHeight(),
MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec, childHeightSpec);
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
} else {
- childHeightSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight(),
+ childHeightSpec = MeasureSpec.makeSafeMeasureSpec(getMeasuredHeight(),
MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec, childHeightSpec);
childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec, mPaddingLeft
+ mPaddingRight, lp.width);
- childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
+ childHeightMeasureSpec = MeasureSpec.makeSafeMeasureSpec(
MeasureSpec.getSize(parentHeightMeasureSpec), MeasureSpec.UNSPECIFIED);
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,
mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin
+ widthUsed, lp.width);
- final int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
+ final int childHeightMeasureSpec = MeasureSpec.makeSafeMeasureSpec(
MeasureSpec.getSize(parentHeightMeasureSpec), MeasureSpec.UNSPECIFIED);
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
View itemView = null;
int itemType = 0;
final int widthMeasureSpec =
- MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.UNSPECIFIED);
+ MeasureSpec.makeSafeMeasureSpec(getMeasuredWidth(), MeasureSpec.UNSPECIFIED);
final int heightMeasureSpec =
- MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.UNSPECIFIED);
+ MeasureSpec.makeSafeMeasureSpec(getMeasuredHeight(), MeasureSpec.UNSPECIFIED);
// Make sure the number of items we'll measure is capped. If it's a huge data set
// with wildly varying sizes, oh well.
// First, measure with no constraint
final int width = MeasureSpec.getSize(widthMeasureSpec);
- final int unspecifiedWidth = MeasureSpec.makeMeasureSpec(width, MeasureSpec.UNSPECIFIED);
+ final int unspecifiedWidth = MeasureSpec.makeSafeMeasureSpec(width,
+ MeasureSpec.UNSPECIFIED);
mImposedTabsHeight = -1;
super.measureHorizontal(unspecifiedWidth, heightMeasureSpec);
spec = getChildMeasureSpec(widthMeasureSpec, 0, LayoutParams.WRAP_CONTENT);
break;
case LayoutParams.MATCH_PARENT:
- spec = MeasureSpec.makeMeasureSpec(
+ spec = MeasureSpec.makeSafeMeasureSpec(
MeasureSpec.getSize(heightMeasureSpec),
MeasureSpec.UNSPECIFIED);
break;
if (mTitleLayout != null && mCustomView == null) {
if (mTitleOptional) {
- final int titleWidthSpec = MeasureSpec.makeMeasureSpec(contentWidth,
+ final int titleWidthSpec = MeasureSpec.makeSafeMeasureSpec(contentWidth,
MeasureSpec.UNSPECIFIED);
mTitleLayout.measure(titleWidthSpec, childSpecHeight);
final int titleWidth = mTitleLayout.getMeasuredWidth();
public void measure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
- tab.measure(View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.UNSPECIFIED),
- View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.UNSPECIFIED));
- text.measure(View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.UNSPECIFIED),
- View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.UNSPECIFIED));
+ tab.measure(View.MeasureSpec.makeSafeMeasureSpec(width, View.MeasureSpec.UNSPECIFIED),
+ View.MeasureSpec.makeSafeMeasureSpec(height, View.MeasureSpec.UNSPECIFIED));
+ text.measure(View.MeasureSpec.makeSafeMeasureSpec(width, View.MeasureSpec.UNSPECIFIED),
+ View.MeasureSpec.makeSafeMeasureSpec(height, View.MeasureSpec.UNSPECIFIED));
}
/**