From 1bb8f51e765d2f2d5f7a479e16d2958849bf3947 Mon Sep 17 00:00:00 2001 From: Alan Viverette Date: Wed, 24 Aug 2016 12:26:27 -0400 Subject: [PATCH] Override LinearLayout's onLayout pass in AlertDialogLayout LinearLayout sets up internal state during onLayout that's missing when we override onMeasure. Avoid calling super.onMeasure() by re-implementing onLayout without the internal state dependencies. Bug: 30494039 Change-Id: I1149517a2fe5f5afdb4125db5e7f573588fea740 --- .../internal/widget/AlertDialogLayout.java | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/core/java/com/android/internal/widget/AlertDialogLayout.java b/core/java/com/android/internal/widget/AlertDialogLayout.java index 891c920af3364..9bf094891f3bb 100644 --- a/core/java/com/android/internal/widget/AlertDialogLayout.java +++ b/core/java/com/android/internal/widget/AlertDialogLayout.java @@ -20,7 +20,9 @@ import android.annotation.AttrRes; import android.annotation.Nullable; import android.annotation.StyleRes; import android.content.Context; +import android.graphics.drawable.Drawable; import android.util.AttributeSet; +import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; @@ -265,4 +267,92 @@ public class AlertDialogLayout extends LinearLayout { return 0; } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + final int paddingLeft = mPaddingLeft; + + // Where right end of child should go + final int width = right - left; + final int childRight = width - mPaddingRight; + + // Space available for child + final int childSpace = width - paddingLeft - mPaddingRight; + + final int totalLength = getMeasuredHeight(); + final int count = getChildCount(); + final int gravity = getGravity(); + final int majorGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK; + final int minorGravity = gravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK; + + int childTop; + switch (majorGravity) { + case Gravity.BOTTOM: + // totalLength contains the padding already + childTop = mPaddingTop + bottom - top - totalLength; + break; + + // totalLength contains the padding already + case Gravity.CENTER_VERTICAL: + childTop = mPaddingTop + (bottom - top - totalLength) / 2; + break; + + case Gravity.TOP: + default: + childTop = mPaddingTop; + break; + } + + final Drawable dividerDrawable = getDividerDrawable(); + final int dividerHeight = dividerDrawable == null ? + 0 : dividerDrawable.getIntrinsicHeight(); + + for (int i = 0; i < count; i++) { + final View child = getChildAt(i); + if (child != null && child.getVisibility() != GONE) { + final int childWidth = child.getMeasuredWidth(); + final int childHeight = child.getMeasuredHeight(); + + final LinearLayout.LayoutParams lp = + (LinearLayout.LayoutParams) child.getLayoutParams(); + + int layoutGravity = lp.gravity; + if (layoutGravity < 0) { + layoutGravity = minorGravity; + } + final int layoutDirection = getLayoutDirection(); + final int absoluteGravity = Gravity.getAbsoluteGravity( + layoutGravity, layoutDirection); + + final int childLeft; + switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) { + case Gravity.CENTER_HORIZONTAL: + childLeft = paddingLeft + ((childSpace - childWidth) / 2) + + lp.leftMargin - lp.rightMargin; + break; + + case Gravity.RIGHT: + childLeft = childRight - childWidth - lp.rightMargin; + break; + + case Gravity.LEFT: + default: + childLeft = paddingLeft + lp.leftMargin; + break; + } + + if (hasDividerBeforeChildAt(i)) { + childTop += dividerHeight; + } + + childTop += lp.topMargin; + setChildFrame(child, childLeft, childTop, childWidth, childHeight); + childTop += childHeight + lp.bottomMargin; + } + } + } + + private void setChildFrame(View child, int left, int top, int width, int height) { + child.layout(left, top, left + width, top + height); + } }