From 9c9573721140c260d4614c7ac58923dcfa0cea22 Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Tue, 4 Jan 2011 17:39:43 -0800 Subject: Make FrameLayout support mixed wrap_content/match_parent children. Bug #3259668 If a FrameLayout is measured with an UNSPECIFIED or AT_MOST spec, it cannot correctly define the size of its children set to match_parent. This change adds a second measurement pass similar to what LinearLayout does in the same situation. Change-Id: I20ac5203c2efc2e559f88b2c9573d4ad7df488b4 --- core/java/android/widget/FrameLayout.java | 62 +++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 7 deletions(-) (limited to 'core/java/android/widget/FrameLayout.java') diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java index 26e191dbf768..7bae3608f1c3 100644 --- a/core/java/android/widget/FrameLayout.java +++ b/core/java/android/widget/FrameLayout.java @@ -29,6 +29,8 @@ import android.view.ViewGroup; import android.view.Gravity; import android.widget.RemoteViews.RemoteView; +import java.util.ArrayList; + /** * FrameLayout is designed to block out an area on the screen to display @@ -46,6 +48,8 @@ import android.widget.RemoteViews.RemoteView; */ @RemoteView public class FrameLayout extends ViewGroup { + private static final int DEFAULT_CHILD_GRAVITY = Gravity.TOP | Gravity.LEFT; + @ViewDebug.ExportedProperty(category = "measurement") boolean mMeasureAllChildren = false; @@ -76,8 +80,8 @@ public class FrameLayout extends ViewGroup { boolean mForegroundBoundsChanged = false; - private static final int DEFAULT_CHILD_GRAVITY = Gravity.TOP | Gravity.LEFT; - + private final ArrayList mMatchParentChildren = new ArrayList(1); + public FrameLayout(Context context) { super(context); } @@ -246,13 +250,17 @@ public class FrameLayout extends ViewGroup { */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - final int count = getChildCount(); + int count = getChildCount(); + + final boolean measureMatchParentChildren = + MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.EXACTLY || + MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY; + mMatchParentChildren.clear(); int maxHeight = 0; int maxWidth = 0; int childState = 0; - // Find rightmost and bottommost child for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (mMeasureAllChildren || child.getVisibility() != GONE) { @@ -260,6 +268,13 @@ public class FrameLayout extends ViewGroup { maxWidth = Math.max(maxWidth, child.getMeasuredWidth()); maxHeight = Math.max(maxHeight, child.getMeasuredHeight()); childState = combineMeasuredStates(childState, child.getMeasuredState()); + if (measureMatchParentChildren) { + final ViewGroup.LayoutParams lp = child.getLayoutParams(); + if (lp.width == LayoutParams.MATCH_PARENT || + lp.height == LayoutParams.MATCH_PARENT) { + mMatchParentChildren.add(child); + } + } } } @@ -280,7 +295,40 @@ public class FrameLayout extends ViewGroup { setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState), resolveSizeAndState(maxHeight, heightMeasureSpec, - childState< 0) { + count = mMatchParentChildren.size(); + for (int i = 0; i < count; i++) { + final View child = mMatchParentChildren.get(i); + + final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); + int childWidthMeasureSpec; + int childHeightMeasureSpec; + + if (lp.width == LayoutParams.MATCH_PARENT) { + childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth() - + mPaddingLeft - mPaddingRight - lp.leftMargin - lp.rightMargin, + MeasureSpec.EXACTLY); + } else { + childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec, + mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin, + lp.width); + } + + if (lp.height == LayoutParams.MATCH_PARENT) { + childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight() - + mPaddingTop - mPaddingBottom - lp.topMargin - lp.bottomMargin, + MeasureSpec.EXACTLY); + } else { + childHeightMeasureSpec = getChildMeasureSpec(widthMeasureSpec, + mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin, + lp.height); + } + + child.measure(childWidthMeasureSpec, childHeightMeasureSpec); + } + } } /** @@ -306,8 +354,8 @@ public class FrameLayout extends ViewGroup { final int width = child.getMeasuredWidth(); final int height = child.getMeasuredHeight(); - int childLeft = parentLeft; - int childTop = parentTop; + int childLeft; + int childTop; int gravity = lp.gravity; if (gravity == -1) { -- cgit v1.2.3