Merge "Tabs are resized to make sure they fit in their parent." into honeycomb
diff --git a/core/java/android/widget/TabWidget.java b/core/java/android/widget/TabWidget.java
index 1a4ff29..22f6f4e 100644
--- a/core/java/android/widget/TabWidget.java
+++ b/core/java/android/widget/TabWidget.java
@@ -66,6 +66,10 @@
private final Rect mBounds = new Rect();
+ // When positive, the widths and heights of tabs will be imposed so that they fit in parent
+ private int mImposedTabsHeight = -1;
+ private int[] mImposedTabWidths;
+
public TabWidget(Context context) {
this(context, null);
}
@@ -150,52 +154,62 @@
setOnFocusChangeListener(this);
}
- /**
- * {@inheritDoc}
- */
@Override
- void measureHorizontal(int widthMeasureSpec, int heightMeasureSpec) {
- // First measure with no constraint
- final int unspecifiedWidth = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
- super.measureHorizontal(unspecifiedWidth, heightMeasureSpec);
+ void measureChildBeforeLayout(View child, int childIndex,
+ int widthMeasureSpec, int totalWidth,
+ int heightMeasureSpec, int totalHeight) {
- final int count = getChildCount();
- int totalWidth = 0;
- int totalCount = 0;
- for (int i = 0; i < count; i++) {
- final View child = getChildAt(i);
- if (child.getVisibility() == GONE) {
- continue;
- }
- final int childWidth = child.getMeasuredWidth();
- totalWidth += childWidth;
- totalCount++;
+ if (mImposedTabsHeight >= 0) {
+ widthMeasureSpec = MeasureSpec.makeMeasureSpec(
+ totalWidth + mImposedTabWidths[childIndex], MeasureSpec.EXACTLY);
+ heightMeasureSpec = MeasureSpec.makeMeasureSpec(mImposedTabsHeight,
+ MeasureSpec.EXACTLY);
}
- final int width = MeasureSpec.getSize(widthMeasureSpec);
- if (totalWidth > width && totalCount > 0) {
- int extraWidth = totalWidth - width;
+ super.measureChildBeforeLayout(child, childIndex,
+ widthMeasureSpec, totalWidth, heightMeasureSpec, totalHeight);
+ }
+
+ @Override
+ void measureHorizontal(int widthMeasureSpec, int heightMeasureSpec) {
+ // First, measure with no constraint
+ final int unspecifiedWidth = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+ super.measureHorizontal(unspecifiedWidth, heightMeasureSpec);
+ mImposedTabsHeight = -1;
+
+ int extraWidth = getMeasuredWidth() - MeasureSpec.getSize(widthMeasureSpec);
+ if (extraWidth > 0) {
+ final int count = getChildCount();
+
+ int childCount = 0;
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
- if (child.getVisibility() == GONE) {
- continue;
- }
- final int childWidth = child.getMeasuredWidth();
- final int delta = extraWidth / totalCount;
- final int tabWidth = Math.max(0, childWidth - delta);
-
- final int tabWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
- tabWidth, MeasureSpec.EXACTLY);
- final int tabHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
- child.getMeasuredHeight(), MeasureSpec.EXACTLY);
-
- child.measure(tabWidthMeasureSpec, tabHeightMeasureSpec);
-
- // Make sure the extra width is evenly distributed, avoiding int division remainder
- extraWidth -= delta;
- totalCount--;
+ if (child.getVisibility() == GONE) continue;
+ childCount++;
}
- setMeasuredDimension(width, getMeasuredHeight());
+
+ if (childCount > 0) {
+ if (mImposedTabWidths == null || mImposedTabWidths.length != count) {
+ mImposedTabWidths = new int[count];
+ }
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ if (child.getVisibility() == GONE) continue;
+ final int childWidth = child.getMeasuredWidth();
+ final int delta = extraWidth / childCount;
+ final int newWidth = Math.max(0, childWidth - delta);
+ mImposedTabWidths[i] = newWidth;
+ // Make sure the extra width is evenly distributed, no int division remainder
+ extraWidth -= childWidth - newWidth; // delta may have been clamped
+ childCount--;
+ mImposedTabsHeight = Math.max(mImposedTabsHeight, child.getMeasuredHeight());
+ }
+ }
+ }
+
+ // Measure again, this time with imposed tab widths and respecting initial spec request
+ if (mImposedTabsHeight >= 0 || unspecifiedWidth != widthMeasureSpec) {
+ super.measureHorizontal(widthMeasureSpec, heightMeasureSpec);
}
}