summaryrefslogtreecommitdiffstats
path: root/core/java/android/widget
diff options
context:
space:
mode:
authorAlan Viverette <alanv@google.com>2015-07-31 12:42:10 -0400
committerAlan Viverette <alanv@google.com>2015-07-31 12:42:10 -0400
commit5a969dfd8e45f6650d3dc35d3438d13754c70c2e (patch)
treea564bcfc69a520da26bd757f0eb64a661ceb1b46 /core/java/android/widget
parent5d6a2d387cd437e6d0c45d0df1bd10ba9db56253 (diff)
downloadframeworks_base-5a969dfd8e45f6650d3dc35d3438d13754c70c2e.zip
frameworks_base-5a969dfd8e45f6650d3dc35d3438d13754c70c2e.tar.gz
frameworks_base-5a969dfd8e45f6650d3dc35d3438d13754c70c2e.tar.bz2
Revert two changes to LinearLayout measurement
"Include non-zero dimension views in excess space calculation" and "Always distribute excess space in LinearLayout measurement" changed LinearLayout behavior significantly in a way that wasn't covered by CTS tests. This reverts commits da2f3044092318d44173bdb9918f31c592b86a73 and 4fabc021583cfd5cc551eda7d7b9809683a6ca9a. Bug: 22862047 Change-Id: I8d37a525ccf295445d3239b80e5cacb10bf3c947
Diffstat (limited to 'core/java/android/widget')
-rw-r--r--core/java/android/widget/LinearLayout.java133
1 files changed, 81 insertions, 52 deletions
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index 47e894a..b5e08ca 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -686,7 +686,6 @@ public class LinearLayout extends ViewGroup {
int weightedMaxWidth = 0;
boolean allFillParent = true;
float totalWeight = 0;
- int usedExcessSpace = 0;
final int count = getVirtualChildCount();
@@ -722,10 +721,8 @@ public class LinearLayout extends ViewGroup {
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) child.getLayoutParams();
totalWeight += lp.weight;
-
- final boolean fillExcessSpace = lp.weight > 0;
- final boolean hasZeroHeight = lp.height == 0;
- if (heightMode == MeasureSpec.EXACTLY && fillExcessSpace && hasZeroHeight) {
+
+ if (heightMode == MeasureSpec.EXACTLY && lp.height == 0 && lp.weight > 0) {
// Optimization: don't bother measuring children who are going to use
// leftover space. These views will get measured again down below if
// there is any leftover space.
@@ -733,12 +730,14 @@ public class LinearLayout extends ViewGroup {
mTotalLength = Math.max(totalLength, totalLength + lp.topMargin + lp.bottomMargin);
skippedMeasure = true;
} else {
- if (fillExcessSpace && hasZeroHeight) {
- // The LinearLayout's heightMode is either UNSPECIFIED or
- // AT_MOST, and this child wanted to stretch to fill
- // available space. Translate the explicit height of 0 to
- // WRAP_CONTENT so that we can measure the view's ideal
- // height.
+ int oldHeight = Integer.MIN_VALUE;
+
+ if (lp.height == 0 && lp.weight > 0) {
+ // heightMode is either UNSPECIFIED or AT_MOST, and this
+ // child wanted to stretch to fill available space.
+ // Translate that to WRAP_CONTENT so that it does not end up
+ // with a height of 0
+ oldHeight = 0;
lp.height = LayoutParams.WRAP_CONTENT;
}
@@ -750,16 +749,11 @@ public class LinearLayout extends ViewGroup {
child, i, widthMeasureSpec, 0, heightMeasureSpec,
totalWeight == 0 ? mTotalLength : 0);
- final int childHeight = child.getMeasuredHeight();
- if (fillExcessSpace) {
- usedExcessSpace += childHeight;
-
- // Restore original layout height.
- if (hasZeroHeight) {
- lp.height = 0;
- }
+ if (oldHeight != Integer.MIN_VALUE) {
+ lp.height = oldHeight;
}
+ final int childHeight = child.getMeasuredHeight();
final int totalLength = mTotalLength;
mTotalLength = Math.max(totalLength, totalLength + childHeight + lp.topMargin +
lp.bottomMargin + getNextLocationOffset(child));
@@ -863,7 +857,7 @@ public class LinearLayout extends ViewGroup {
// Either expand children with weight to take up available space or
// shrink them if they extend beyond our current bounds. If we skipped
// measurement on any children, we need to measure them now.
- final int delta = heightSize - mTotalLength + usedExcessSpace;
+ int delta = heightSize - mTotalLength;
if (skippedMeasure || delta != 0 && totalWeight > 0.0f) {
float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
@@ -880,14 +874,34 @@ public class LinearLayout extends ViewGroup {
float childExtra = lp.weight;
if (childExtra > 0) {
- // Distribute excess space to child.
- final int childHeight = Math.max(0, (int) (childExtra * delta / weightSum));
- final int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(childHeight,
- MeasureSpec.EXACTLY);
+ // Child said it could absorb extra space -- give him his share
+ int share = (int) (childExtra * delta / weightSum);
+ weightSum -= childExtra;
+ delta -= share;
+
final int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
- mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin,
- lp.width);
- child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+ mPaddingLeft + mPaddingRight +
+ lp.leftMargin + lp.rightMargin, lp.width);
+
+ // TODO: Use a field like lp.isMeasured to figure out if this
+ // child has been previously measured
+ if ((lp.height != 0) || (heightMode != MeasureSpec.EXACTLY)) {
+ // child was measured once already above...
+ // base new measurement on stored values
+ int childHeight = child.getMeasuredHeight() + share;
+ if (childHeight < 0) {
+ childHeight = 0;
+ }
+
+ child.measure(childWidthMeasureSpec,
+ MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.EXACTLY));
+ } else {
+ // child was skipped in the loop above.
+ // Measure for this first time here
+ child.measure(childWidthMeasureSpec,
+ MeasureSpec.makeMeasureSpec(share > 0 ? share : 0,
+ MeasureSpec.EXACTLY));
+ }
// Child may now not fit in vertical dimension.
childState = combineMeasuredStates(childState, child.getMeasuredState()
@@ -1003,7 +1017,6 @@ public class LinearLayout extends ViewGroup {
int weightedMaxHeight = 0;
boolean allFillParent = true;
float totalWeight = 0;
- int usedExcessSpace = 0;
final int count = getVirtualChildCount();
@@ -1053,10 +1066,8 @@ public class LinearLayout extends ViewGroup {
child.getLayoutParams();
totalWeight += lp.weight;
-
- final boolean fillExcessSpace = lp.weight > 0;
- final boolean hasZeroWidth = lp.width == 0;
- if (widthMode == MeasureSpec.EXACTLY && fillExcessSpace && hasZeroWidth) {
+
+ if (widthMode == MeasureSpec.EXACTLY && lp.width == 0 && lp.weight > 0) {
// Optimization: don't bother measuring children who are going to use
// leftover space. These views will get measured again down below if
// there is any leftover space.
@@ -1083,12 +1094,14 @@ public class LinearLayout extends ViewGroup {
skippedMeasure = true;
}
} else {
- if (fillExcessSpace && hasZeroWidth) {
- // The LinearLayout's widthMode is either UNSPECIFIED or
- // AT_MOST, and this child wanted to stretch to fill
- // available space. Translate the explicit height of 0 to
- // WRAP_CONTENT so that we can measure the view's ideal
- // width.
+ int oldWidth = Integer.MIN_VALUE;
+
+ if (lp.width == 0 && lp.weight > 0) {
+ // widthMode is either UNSPECIFIED or AT_MOST, and this
+ // child
+ // wanted to stretch to fill available space. Translate that to
+ // WRAP_CONTENT so that it does not end up with a width of 0
+ oldWidth = 0;
lp.width = LayoutParams.WRAP_CONTENT;
}
@@ -1100,16 +1113,11 @@ public class LinearLayout extends ViewGroup {
totalWeight == 0 ? mTotalLength : 0,
heightMeasureSpec, 0);
- final int childWidth = child.getMeasuredWidth();
- if (fillExcessSpace) {
- usedExcessSpace += childWidth;
-
- // Restore the original layout width.
- if (hasZeroWidth) {
- lp.width = 0;
- }
+ if (oldWidth != Integer.MIN_VALUE) {
+ lp.width = oldWidth;
}
+ final int childWidth = child.getMeasuredWidth();
if (isExactly) {
mTotalLength += childWidth + lp.leftMargin + lp.rightMargin +
getNextLocationOffset(child);
@@ -1234,7 +1242,7 @@ public class LinearLayout extends ViewGroup {
// Either expand children with weight to take up available space or
// shrink them if they extend beyond our current bounds. If we skipped
// measurement on any children, we need to measure them now.
- final int delta = widthSize - mTotalLength + usedExcessSpace;
+ int delta = widthSize - mTotalLength;
if (skippedMeasure || delta != 0 && totalWeight > 0.0f) {
float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
@@ -1257,13 +1265,34 @@ public class LinearLayout extends ViewGroup {
float childExtra = lp.weight;
if (childExtra > 0) {
// Child said it could absorb extra space -- give him his share
- final int childWidth = Math.max(0, (int) (childExtra * delta / weightSum));
- final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidth,
- MeasureSpec.EXACTLY);
- final int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
+ int share = (int) (childExtra * delta / weightSum);
+ weightSum -= childExtra;
+ delta -= share;
+
+ final int childHeightMeasureSpec = getChildMeasureSpec(
+ heightMeasureSpec,
mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin,
lp.height);
- child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+
+ // TODO: Use a field like lp.isMeasured to figure out if this
+ // child has been previously measured
+ if ((lp.width != 0) || (widthMode != MeasureSpec.EXACTLY)) {
+ // child was measured once already above ... base new measurement
+ // on stored values
+ int childWidth = child.getMeasuredWidth() + share;
+ if (childWidth < 0) {
+ childWidth = 0;
+ }
+
+ child.measure(
+ MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY),
+ childHeightMeasureSpec);
+ } else {
+ // child was skipped in the loop above. Measure for this first time here
+ child.measure(MeasureSpec.makeMeasureSpec(
+ share > 0 ? share : 0, MeasureSpec.EXACTLY),
+ childHeightMeasureSpec);
+ }
// Child may now not fit in horizontal dimension.
childState = combineMeasuredStates(childState,