diff options
| -rw-r--r-- | core/java/android/widget/LinearLayout.java | 109 | ||||
| -rw-r--r-- | core/res/res/layout/alert_dialog.xml | 3 | ||||
| -rw-r--r-- | core/res/res/values/attrs.xml | 4 |
3 files changed, 95 insertions, 21 deletions
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java index 0ce70fad326f..5c78af51e136 100644 --- a/core/java/android/widget/LinearLayout.java +++ b/core/java/android/widget/LinearLayout.java @@ -94,6 +94,9 @@ public class LinearLayout extends ViewGroup { @ViewDebug.ExportedProperty private float mWeightSum; + @ViewDebug.ExportedProperty + private boolean mUseLargestChild; + private int[] mMaxAscent; private int[] mMaxDescent; @@ -102,7 +105,7 @@ public class LinearLayout extends ViewGroup { private static final int INDEX_CENTER_VERTICAL = 0; private static final int INDEX_TOP = 1; private static final int INDEX_BOTTOM = 2; - private static final int INDEX_FILL = 3; + private static final int INDEX_FILL = 3; public LinearLayout(Context context) { super(context); @@ -134,6 +137,9 @@ public class LinearLayout extends ViewGroup { mBaselineAlignedChildIndex = a.getInt(com.android.internal.R.styleable.LinearLayout_baselineAlignedChildIndex, -1); + // TODO: Better name, add Java APIs, make it public + mUseLargestChild = a.getBoolean(R.styleable.LinearLayout_useLargestChild, false); + a.recycle(); } @@ -328,6 +334,9 @@ public class LinearLayout extends ViewGroup { boolean matchWidth = false; final int baselineChildIndex = mBaselineAlignedChildIndex; + final boolean useLargestChild = mUseLargestChild; + + int largestChildHeight = Integer.MIN_VALUE; // See how tall everyone is. Also remember max width. for (int i = 0; i < count; ++i) { @@ -353,30 +362,35 @@ public class LinearLayout extends ViewGroup { // there is any leftover space. mTotalLength += lp.topMargin + lp.bottomMargin; } else { - int oldHeight = Integer.MIN_VALUE; + int oldHeight = Integer.MIN_VALUE; - if (lp.height == 0 && lp.weight > 0) { + 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; - } + } - // Determine how big this child would like to. If this or - // previous children have given a weight, then we allow it to - // use all available space (and we will shrink things later - // if needed). - measureChildBeforeLayout( + // Determine how big this child would like to. If this or + // previous children have given a weight, then we allow it to + // use all available space (and we will shrink things later + // if needed). + measureChildBeforeLayout( child, i, widthMeasureSpec, 0, heightMeasureSpec, totalWeight == 0 ? mTotalLength : 0); - if (oldHeight != Integer.MIN_VALUE) { + if (oldHeight != Integer.MIN_VALUE) { lp.height = oldHeight; - } + } - mTotalLength += child.getMeasuredHeight() + lp.topMargin + + final int childHeight = child.getMeasuredHeight(); + mTotalLength += childHeight + lp.topMargin + lp.bottomMargin + getNextLocationOffset(child); + + if (useLargestChild) { + largestChildHeight = Math.max(childHeight, largestChildHeight); + } } /** @@ -426,7 +440,30 @@ public class LinearLayout extends ViewGroup { i += getChildrenSkipCount(child, i); } - + + if (useLargestChild) { + mTotalLength = 0; + + for (int i = 0; i < count; ++i) { + final View child = getVirtualChildAt(i); + + if (child == null) { + mTotalLength += measureNullChild(i); + continue; + } + + if (child.getVisibility() == GONE) { + i += getChildrenSkipCount(child, i); + continue; + } + + final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) + child.getLayoutParams(); + mTotalLength += largestChildHeight + lp.topMargin+ lp.bottomMargin + + getNextLocationOffset(child); + } + } + // Add in our padding mTotalLength += mPaddingTop + mPaddingBottom; @@ -587,6 +624,9 @@ public class LinearLayout extends ViewGroup { maxDescent[0] = maxDescent[1] = maxDescent[2] = maxDescent[3] = -1; final boolean baselineAligned = mBaselineAligned; + final boolean useLargestChild = mUseLargestChild; + + int largestChildWidth = Integer.MIN_VALUE; // See how wide everyone is. Also remember max height. for (int i = 0; i < count; ++i) { @@ -602,7 +642,8 @@ public class LinearLayout extends ViewGroup { continue; } - final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) child.getLayoutParams(); + final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) + child.getLayoutParams(); totalWeight += lp.weight; @@ -643,9 +684,14 @@ public class LinearLayout extends ViewGroup { if (oldWidth != Integer.MIN_VALUE) { lp.width = oldWidth; } - - mTotalLength += child.getMeasuredWidth() + lp.leftMargin + - lp.rightMargin + getNextLocationOffset(child); + + final int childWidth = child.getMeasuredWidth(); + mTotalLength += childWidth + lp.leftMargin + lp.rightMargin + + getNextLocationOffset(child); + + if (useLargestChild) { + largestChildWidth = Math.max(childWidth, largestChildWidth); + } } boolean matchHeightLocally = false; @@ -708,6 +754,29 @@ public class LinearLayout extends ViewGroup { maxHeight = Math.max(maxHeight, ascent + descent); } + if (useLargestChild) { + mTotalLength = 0; + + for (int i = 0; i < count; ++i) { + final View child = getVirtualChildAt(i); + + if (child == null) { + mTotalLength += measureNullChild(i); + continue; + } + + if (child.getVisibility() == GONE) { + i += getChildrenSkipCount(child, i); + continue; + } + + final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) + child.getLayoutParams(); + mTotalLength += largestChildWidth + lp.leftMargin + lp.rightMargin + + getNextLocationOffset(child); + } + } + // Add in our padding mTotalLength += mPaddingLeft + mPaddingRight; @@ -953,7 +1022,7 @@ public class LinearLayout extends ViewGroup { final int paddingLeft = mPaddingLeft; int childTop = mPaddingTop; - int childLeft = paddingLeft; + int childLeft; // Where right end of child should go final int width = mRight - mLeft; @@ -1038,7 +1107,7 @@ public class LinearLayout extends ViewGroup { void layoutHorizontal() { final int paddingTop = mPaddingTop; - int childTop = paddingTop; + int childTop; int childLeft = mPaddingLeft; // Where bottom of child should go @@ -1103,7 +1172,7 @@ public class LinearLayout extends ViewGroup { break; case Gravity.CENTER_VERTICAL: - // Removed support for baselign alignment when layout_gravity or + // Removed support for baseline alignment when layout_gravity or // gravity == center_vertical. See bug #1038483. // Keep the code around if we need to re-enable this feature // if (childBaseline != -1) { diff --git a/core/res/res/layout/alert_dialog.xml b/core/res/res/layout/alert_dialog.xml index 409dcd310f7f..4a63c5bde85e 100644 --- a/core/res/res/layout/alert_dialog.xml +++ b/core/res/res/layout/alert_dialog.xml @@ -109,7 +109,8 @@ android:orientation="horizontal" android:paddingTop="4dip" android:paddingLeft="2dip" - android:paddingRight="2dip" > + android:paddingRight="2dip" + android:useLargestChild="true"> <LinearLayout android:id="@+id/leftSpacer" android:layout_weight="0.25" android:layout_width="0dip" diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 8dadd88ac0e7..140ab098b3c6 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -1700,6 +1700,10 @@ space by giving it a layout_weight of 0.5 and setting the weightSum to 1.0. --> <attr name="weightSum" format="float" /> + <!-- When set to true, all children with a weight will be considered having + the minimum size of the largest child. If false, all children are + measured normally. --> + <attr name="useLargestChild" format="boolean" /> </declare-styleable> <declare-styleable name="ListView"> <!-- Reference to an array resource that will populate the ListView. For static content, |