diff options
author | Philip Milne <pmilne@google.com> | 2011-06-09 18:30:32 -0700 |
---|---|---|
committer | Philip Milne <pmilne@google.com> | 2011-06-10 10:51:45 -0700 |
commit | f474870fe1189f73cf8ffbaba9e524ef194b5043 (patch) | |
tree | eca5a08ddacc888a57576cd018a46ee5a967202d | |
parent | f7728ae964f180081c8e1cb11c01d36e85dc8650 (diff) | |
download | frameworks_base-f474870fe1189f73cf8ffbaba9e524ef194b5043.zip frameworks_base-f474870fe1189f73cf8ffbaba9e524ef194b5043.tar.gz frameworks_base-f474870fe1189f73cf8ffbaba9e524ef194b5043.tar.bz2 |
Optimise the way that indices are auto-allocated so that XML files can normally avoid using indices.
Change-Id: Iafb25b17fec9391664c81a7e213eeaa918254912
4 files changed, 144 insertions, 140 deletions
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java index 9834485..bda82a3 100644 --- a/core/java/android/widget/GridLayout.java +++ b/core/java/android/widget/GridLayout.java @@ -536,70 +536,76 @@ public class GridLayout extends ViewGroup { return margin == UNDEFINED ? getDefaultMarginValue(view, lp, leading, horizontal) : margin; } - private static boolean isUndefined(Interval span) { - return span.min == UNDEFINED || span.max == UNDEFINED; + private static int valueIfDefined(int value, int defaultValue) { + return (value != UNDEFINED) ? value : defaultValue; } + // install default indices for cells that don't define them private void validateLayoutParams() { - // install default indices for cells if *none* are defined - if (mHorizontalAxis.maxIndex1() == UNDEFINED || (mVerticalAxis.maxIndex1() == UNDEFINED)) { - boolean horizontal = mOrientation == HORIZONTAL; - int count = horizontal ? mHorizontalAxis.count : mVerticalAxis.count; - if (count == UNDEFINED) { - count = Integer.MAX_VALUE; - } - int x = 0; - int y = 0; - int maxSize = 0; - for (int i = 0, size = getChildCount(); i < size; i++) { - LayoutParams lp = getLayoutParams1(getChildAt(i)); + new Object() { + public int maxSize = 0; - Interval hSpan = lp.columnGroup.span; - int cellWidth = hSpan.size(); + private int valueIfDefined2(int value, int defaultValue) { + if (value != UNDEFINED) { + maxSize = 0; + return value; + } else { + return defaultValue; + } + } - Interval vSpan = lp.rowGroup.span; - int cellHeight = vSpan.size(); + { + final boolean horizontal = (mOrientation == HORIZONTAL); + final int axis = horizontal ? mHorizontalAxis.count : mVerticalAxis.count; + final int count = valueIfDefined(axis, Integer.MAX_VALUE); - if (horizontal) { - if (x + cellWidth > count) { - x = 0; - y += maxSize; - maxSize = 0; - } - } else { - if (y + cellHeight > count) { - y = 0; - x += maxSize; - maxSize = 0; + int row = 0; + int col = 0; + for (int i = 0, N = getChildCount(); i < N; i++) { + LayoutParams lp = getLayoutParams1(getChildAt(i)); + + Group colGroup = lp.columnGroup; + Interval cols = colGroup.span; + int colSpan = cols.size(); + + Group rowGroup = lp.rowGroup; + Interval rows = rowGroup.span; + int rowSpan = rows.size(); + + if (horizontal) { + row = valueIfDefined2(rows.min, row); + + int newCol = valueIfDefined(cols.min, (col + colSpan > count) ? 0 : col); + if (newCol < col) { + row += maxSize; + maxSize = 0; + } + col = newCol; + maxSize = max(maxSize, rowSpan); + } else { + col = valueIfDefined2(cols.min, col); + + int newRow = valueIfDefined(rows.min, (row + rowSpan > count) ? 0 : row); + if (newRow < row) { + col += maxSize; + maxSize = 0; + } + row = newRow; + maxSize = max(maxSize, colSpan); } - } - lp.setHorizontalGroupSpan(new Interval(x, x + cellWidth)); - lp.setVerticalGroupSpan(new Interval(y, y + cellHeight)); - if (horizontal) { - x = x + cellWidth; - } else { - y = y + cellHeight; - } - maxSize = max(maxSize, horizontal ? cellHeight : cellWidth); - } - } else { - /* - At least one row and one column index have been defined. - Assume missing row/cols are in error and set them to zero so that - they will display top/left and the developer can add the right indices. - Without this UNDEFINED would cause ArrayIndexOutOfBoundsException. - */ - for (int i = 0, size = getChildCount(); i < size; i++) { - LayoutParams lp = getLayoutParams1(getChildAt(i)); - if (isUndefined(lp.columnGroup.span)) { - lp.setHorizontalGroupSpan(LayoutParams.DEFAULT_SPAN); - } - if (isUndefined(lp.rowGroup.span)) { - lp.setVerticalGroupSpan(LayoutParams.DEFAULT_SPAN); + lp.setColumnGroupSpan(new Interval(col, col + colSpan)); + lp.setRowGroupSpan(new Interval(row, row + rowSpan)); + + if (horizontal) { + col = col + colSpan; + } else { + row = row + rowSpan; + } } } - } + }; + invalidateStructure(); } private void invalidateStructure() { @@ -927,13 +933,11 @@ public class GridLayout extends ViewGroup { this.horizontal = horizontal; } - private int maxIndex(boolean internal) { + private int maxIndex() { // note the number Integer.MIN_VALUE + 1 comes up in undefined cells int count = -1; for (int i = 0, size = getChildCount(); i < size; i++) { - LayoutParams params = internal ? - getLayoutParams1(getChildAt(i)) : - getLayoutParams(getChildAt(i)); + LayoutParams params = getLayoutParams(getChildAt(i)); Group g = horizontal ? params.columnGroup : params.rowGroup; count = max(count, g.span.min); count = max(count, g.span.max); @@ -941,13 +945,9 @@ public class GridLayout extends ViewGroup { return count == -1 ? UNDEFINED : count; } - private int maxIndex1() { - return maxIndex(true); - } - public int getCount() { - if (!countWasExplicitySet && !countValid) { - count = max(0, maxIndex(false)); // if there are no cells, the count is zero + if (!countValid) { + count = max(0, maxIndex()); // if there are no cells, the count is zero countValid = true; } return count; @@ -1391,7 +1391,7 @@ public class GridLayout extends ViewGroup { private float[] getWeights() { if (weights == null) { - int N = getCount() + 1; + int N = getCount(); weights = new float[N]; } computeWeights(); @@ -1424,7 +1424,7 @@ public class GridLayout extends ViewGroup { float[] weights = getWeights(); float totalWeight = sum(weights); - if (totalWeight == 0f) { + if (totalWeight == 0f && weights.length > 0) { weights[weights.length - 1] = 1; totalWeight = 1; } @@ -1432,11 +1432,12 @@ public class GridLayout extends ViewGroup { int[] locations = getLocations(); int cumulativeDelta = 0; - for (int i = 0; i < locations.length; i++) { + // note |weights| = |locations| - 1 + for (int i = 0; i < weights.length; i++) { float weight = weights[i]; int delta = (int) (totalDelta * weight / totalWeight); cumulativeDelta += delta; - locations[i] = mins[i] + cumulativeDelta; + locations[i + 1] = mins[i + 1] + cumulativeDelta; totalDelta -= delta; totalWeight -= weight; @@ -1534,22 +1535,22 @@ public class GridLayout extends ViewGroup { private static final int DEFAULT_MARGIN = UNDEFINED; private static final int DEFAULT_ROW = UNDEFINED; private static final int DEFAULT_COLUMN = UNDEFINED; - private static final Interval DEFAULT_SPAN = new Interval(0, 1); + private static final Interval DEFAULT_SPAN = new Interval(UNDEFINED, UNDEFINED + 1); private static final int DEFAULT_SPAN_SIZE = DEFAULT_SPAN.size(); - private static final Alignment DEFAULT_HORIZONTAL_ALIGNMENT = LEFT; - private static final Alignment DEFAULT_VERTCIAL_ALGIGNMENT = BASELINE; - private static final Group DEFAULT_HORIZONTAL_GROUP = - new Group(DEFAULT_SPAN, DEFAULT_HORIZONTAL_ALIGNMENT); - private static final Group DEFAULT_VERTICAL_GROUP = - new Group(DEFAULT_SPAN, DEFAULT_VERTCIAL_ALGIGNMENT); + private static final Alignment DEFAULT_COLUMN_ALIGNMENT = LEFT; + private static final Alignment DEFAULT_ROW_ALIGNMENT = BASELINE; + private static final Group DEFAULT_COLUMN_GROUP = + new Group(DEFAULT_SPAN, DEFAULT_COLUMN_ALIGNMENT); + private static final Group DEFAULT_ROW_GROUP = + new Group(DEFAULT_SPAN, DEFAULT_ROW_ALIGNMENT); private static final int DEFAULT_WEIGHT_0 = 0; private static final int DEFAULT_WEIGHT_1 = 1; // Misc private static final Rect CONTAINER_BOUNDS = new Rect(0, 0, 2, 2); - private static final Alignment[] HORIZONTAL_ALIGNMENTS = { LEFT, CENTER, RIGHT }; - private static final Alignment[] VERTICAL_ALIGNMENTS = { TOP, CENTER, BOTTOM }; + private static final Alignment[] COLUMN_ALIGNMENTS = { LEFT, CENTER, RIGHT }; + private static final Alignment[] ROW_ALIGNMENTS = { TOP, CENTER, BOTTOM }; // TypedArray indices @@ -1623,7 +1624,7 @@ public class GridLayout extends ViewGroup { * Constructs a new LayoutParams with default values as defined in {@link LayoutParams}. */ public LayoutParams() { - this(DEFAULT_HORIZONTAL_GROUP, DEFAULT_VERTICAL_GROUP); + this(DEFAULT_ROW_GROUP, DEFAULT_COLUMN_GROUP); } // Copying constructors @@ -1714,23 +1715,23 @@ public class GridLayout extends ViewGroup { // Gravity. For conversion from the static the integers defined in the Gravity class, // use Gravity.apply() to apply gravity to a view of zero size and see where it ends up. - private static Alignment getHorizontalAlignment(int gravity, int width) { + private static Alignment getColumnAlignment(int gravity, int width) { Rect r = new Rect(0, 0, 0, 0); Gravity.apply(gravity, 0, 0, CONTAINER_BOUNDS, r); - boolean fill = width == MATCH_PARENT; - Alignment defaultAlignment = fill ? FILL : DEFAULT_HORIZONTAL_ALIGNMENT; - return getAlignment(HORIZONTAL_ALIGNMENTS, FILL, r.left, r.right, + boolean fill = (width == MATCH_PARENT); + Alignment defaultAlignment = fill ? FILL : DEFAULT_COLUMN_ALIGNMENT; + return getAlignment(COLUMN_ALIGNMENTS, FILL, r.left, r.right, !definesHorizontal(gravity), defaultAlignment); } - private static Alignment getVerticalAlignment(int gravity, int height) { + private static Alignment getRowAlignment(int gravity, int height) { Rect r = new Rect(0, 0, 0, 0); Gravity.apply(gravity, 0, 0, CONTAINER_BOUNDS, r); - boolean fill = height == MATCH_PARENT; - Alignment defaultAlignment = fill ? FILL : DEFAULT_VERTCIAL_ALGIGNMENT; - return getAlignment(VERTICAL_ALIGNMENTS, FILL, r.top, r.bottom, + boolean fill = (height == MATCH_PARENT); + Alignment defaultAlignment = fill ? FILL : DEFAULT_ROW_ALIGNMENT; + return getAlignment(ROW_ALIGNMENTS, FILL, r.top, r.bottom, !definesVertical(gravity), defaultAlignment); } @@ -1746,13 +1747,13 @@ public class GridLayout extends ViewGroup { int column = a.getInteger(COLUMN, DEFAULT_COLUMN); int columnSpan = a.getInteger(COLUMN_SPAN, DEFAULT_SPAN_SIZE); Interval hSpan = new Interval(column, column + columnSpan); - this.columnGroup = new Group(hSpan, getHorizontalAlignment(gravity, width)); + this.columnGroup = new Group(hSpan, getColumnAlignment(gravity, width)); this.columnWeight = a.getFloat(COLUMN_WEIGHT, getDefaultWeight(width)); int row = a.getInteger(ROW, DEFAULT_ROW); int rowSpan = a.getInteger(ROW_SPAN, DEFAULT_SPAN_SIZE); Interval vSpan = new Interval(row, row + rowSpan); - this.rowGroup = new Group(vSpan, getVerticalAlignment(gravity, height)); + this.rowGroup = new Group(vSpan, getRowAlignment(gravity, height)); this.rowWeight = a.getFloat(ROW_WEIGHT, getDefaultWeight(height)); } finally { a.recycle(); @@ -1768,8 +1769,8 @@ public class GridLayout extends ViewGroup { * @attr ref android.R.styleable#GridLayout_Layout_layout_gravity */ public void setGravity(int gravity) { - columnGroup = columnGroup.copyWriteAlignment(getHorizontalAlignment(gravity, width)); - rowGroup = rowGroup.copyWriteAlignment(getVerticalAlignment(gravity, height)); + columnGroup = columnGroup.copyWriteAlignment(getColumnAlignment(gravity, width)); + rowGroup = rowGroup.copyWriteAlignment(getRowAlignment(gravity, height)); } @Override @@ -1778,11 +1779,11 @@ public class GridLayout extends ViewGroup { this.height = attributes.getLayoutDimension(heightAttr, DEFAULT_HEIGHT); } - private void setVerticalGroupSpan(Interval span) { + private void setRowGroupSpan(Interval span) { rowGroup = rowGroup.copyWriteSpan(span); } - private void setHorizontalGroupSpan(Interval span) { + private void setColumnGroupSpan(Interval span) { columnGroup = columnGroup.copyWriteSpan(span); } } @@ -2073,30 +2074,30 @@ public class GridLayout extends ViewGroup { /** * Construct a new Group, {@code group}, where: * <ul> - * <li> {@code group.span = [min, max]} </li> + * <li> {@code group.span = [start, start + size]} </li> * <li> {@code group.alignment = alignment} </li> * </ul> * - * @param min the minimum - * @param max the maximum + * @param start the start + * @param size the size * @param alignment the alignment */ - public Group(int min, int max, Alignment alignment) { - this(new Interval(min, max), alignment); + public Group(int start, int size, Alignment alignment) { + this(new Interval(start, start + size), alignment); } /** * Construct a new Group, {@code group}, where: * <ul> - * <li> {@code group.span = [min, min + 1]} </li> + * <li> {@code group.span = [start, start + 1]} </li> * <li> {@code group.alignment = alignment} </li> * </ul> * - * @param min the minimum + * @param start the start index * @param alignment the alignment */ - public Group(int min, Alignment alignment) { - this(min, min + 1, alignment); + public Group(int start, Alignment alignment) { + this(start, 1, alignment); } private Group copyWriteSpan(Interval span) { diff --git a/tests/GridLayoutTest/res/layout/grid3.xml b/tests/GridLayoutTest/res/layout/grid3.xml index ace7b4c..31dc75a 100644 --- a/tests/GridLayoutTest/res/layout/grid3.xml +++ b/tests/GridLayoutTest/res/layout/grid3.xml @@ -19,59 +19,61 @@ android:layout_width="match_parent" android:layout_height="match_parent" + android:useDefaultMargins="true" + android:marginsIncludedInAlignment="false" + android:columnCount="4" > - <Button - android:text="fill" - android:width="200dip" - android:height="100dip" - android:layout_marginLeft="50dip" - android:layout_row="0" - android:layout_column="0" - android:layout_gravity="fill_horizontal" + <TextView + android:text="Email account" + android:textSize="48dip" + android:layout_columnSpan="4" + android:layout_gravity="center_horizontal" /> - <EditText - android:layout_row="0" - android:layout_column="1" + <TextView + android:text="You can configure email in just a few steps:" + android:textSize="20dip" + android:layout_columnSpan="4" + android:layout_gravity="left" /> - <Button - android:text="left" - android:layout_row="1" - android:layout_column="0" + <TextView + android:text="Email address:" + android:layout_gravity="right" /> <EditText - android:layout_row="1" - android:layout_column="1" + android:layout_width="100dip" /> - <Button - android:text="right" - android:layout_row="2" + <TextView + android:text="Password:" android:layout_column="0" android:layout_gravity="right" /> <EditText - android:layout_margin="50dip" - android:textSize="100dip" - android:layout_row="2" - android:layout_column="1" + android:layout_width="50dip" /> - <Button - android:text="center" - android:layout_row="3" - android:layout_column="0" - android:layout_gravity="center_horizontal" + <Space + android:layout_rowWeight="1" + android:layout_columnWeight="1" + android:layout_row="4" + android:layout_column="2" /> - <EditText - android:layout_height="fill_parent" - android:layout_row="3" - android:layout_column="1" + <Button + android:text="Manual setup" + android:layout_row="5" + android:layout_column="3" + android:layout_gravity="fill_horizontal" /> + <Button + android:text="Next" + android:layout_column="3" + android:layout_gravity="fill_horizontal" + /> </GridLayout> diff --git a/tests/GridLayoutTest/src/com/android/test/layout/AbstractLayoutTest.java b/tests/GridLayoutTest/src/com/android/test/layout/AbstractLayoutTest.java index 937eacb..4d3a843 100644 --- a/tests/GridLayoutTest/src/com/android/test/layout/AbstractLayoutTest.java +++ b/tests/GridLayoutTest/src/com/android/test/layout/AbstractLayoutTest.java @@ -19,19 +19,19 @@ package com.android.test.layout; import android.app.Activity; import android.content.Context; import android.os.Bundle; -import android.os.Debug; import android.util.Log; -import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.widget.Button; +import static android.view.Gravity.*; + public abstract class AbstractLayoutTest extends Activity { - public static final String[] HORIZONTAL_NAMES = new String[] { "LEFT", "center", "east", "fill" }; - public static final int[] HORIZONTAL_ALIGNMENTS = new int[] { Gravity.LEFT, Gravity.CENTER, Gravity.RIGHT, Gravity.FILL }; - public static final String[] VERTICAL_NAMES = new String[] { "north", "center", "baseline", "south", "fill" }; - public static final int[] VERTICAL_ALIGNMENTS = new int[] { Gravity.TOP, Gravity.CENTER, Gravity.NO_GRAVITY, Gravity.BOTTOM, Gravity.FILL }; + public static final String[] HORIZONTAL_NAMES = { "LEFT", "CENTER", "RIGHT", "FILL" }; + public static final int[] HORIZONTAL_ALIGNMENTS = { LEFT, CENTER, RIGHT, FILL }; + public static final String[] VERTICAL_NAMES = { "TOP", "CENTER", "BASELINE", "BOTTOM", "FILL" }; + public static final int[] VERTICAL_ALIGNMENTS = { TOP, CENTER, NO_GRAVITY, BOTTOM, FILL }; public View create(Context context, String name, int size) { Button result = new Button(context); diff --git a/tests/GridLayoutTest/src/com/android/test/layout/GridLayoutTest.java b/tests/GridLayoutTest/src/com/android/test/layout/GridLayoutTest.java index 2eecb8a..c5681e2 100644 --- a/tests/GridLayoutTest/src/com/android/test/layout/GridLayoutTest.java +++ b/tests/GridLayoutTest/src/com/android/test/layout/GridLayoutTest.java @@ -36,6 +36,7 @@ public class GridLayoutTest extends AbstractLayoutTest { GridLayout.Group rowGroup = new GridLayout.Group(UNDEFINED, null); GridLayout.Group colGroup = new GridLayout.Group(UNDEFINED, null); GridLayout.LayoutParams lp = new GridLayout.LayoutParams(rowGroup, colGroup); + //GridLayout.LayoutParams lp = new GridLayout.LayoutParams(); lp.setGravity(va | ha); View v = create(context, VERTICAL_NAMES[i] + "-" + HORIZONTAL_NAMES[j], 20); container.addView(v, lp); |