Optimise the way that indices are auto-allocated so that XML files can normally avoid using indices.
Change-Id: Iafb25b17fec9391664c81a7e213eeaa918254912
This commit is contained in:
@@ -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();
|
||||
|
||||
Interval vSpan = lp.rowGroup.span;
|
||||
int cellHeight = vSpan.size();
|
||||
|
||||
if (horizontal) {
|
||||
if (x + cellWidth > count) {
|
||||
x = 0;
|
||||
y += maxSize;
|
||||
maxSize = 0;
|
||||
}
|
||||
private int valueIfDefined2(int value, int defaultValue) {
|
||||
if (value != UNDEFINED) {
|
||||
maxSize = 0;
|
||||
return value;
|
||||
} else {
|
||||
if (y + cellHeight > count) {
|
||||
y = 0;
|
||||
x += maxSize;
|
||||
maxSize = 0;
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
final boolean horizontal = (mOrientation == HORIZONTAL);
|
||||
final int axis = horizontal ? mHorizontalAxis.count : mVerticalAxis.count;
|
||||
final int count = valueIfDefined(axis, Integer.MAX_VALUE);
|
||||
|
||||
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.setColumnGroupSpan(new Interval(col, col + colSpan));
|
||||
lp.setRowGroupSpan(new Interval(row, row + rowSpan));
|
||||
|
||||
if (horizontal) {
|
||||
col = col + colSpan;
|
||||
} else {
|
||||
row = row + rowSpan;
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
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) {
|
||||
|
||||
@@ -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"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:text="You can configure email in just a few steps:"
|
||||
android:textSize="20dip"
|
||||
android:layout_columnSpan="4"
|
||||
android:layout_gravity="left"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:text="Email address:"
|
||||
android:layout_gravity="right"
|
||||
/>
|
||||
|
||||
<EditText
|
||||
android:layout_row="0"
|
||||
android:layout_column="1"
|
||||
android:layout_width="100dip"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:text="left"
|
||||
android:layout_row="1"
|
||||
android:layout_column="0"
|
||||
/>
|
||||
|
||||
<EditText
|
||||
android:layout_row="1"
|
||||
android:layout_column="1"
|
||||
/>
|
||||
|
||||
<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"
|
||||
/>
|
||||
|
||||
<Space
|
||||
android:layout_rowWeight="1"
|
||||
android:layout_columnWeight="1"
|
||||
android:layout_row="4"
|
||||
android:layout_column="2"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:text="center"
|
||||
android:layout_row="3"
|
||||
android:layout_column="0"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="Manual setup"
|
||||
android:layout_row="5"
|
||||
android:layout_column="3"
|
||||
android:layout_gravity="fill_horizontal"
|
||||
/>
|
||||
|
||||
<EditText
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_row="3"
|
||||
android:layout_column="1"
|
||||
<Button
|
||||
android:text="Next"
|
||||
android:layout_column="3"
|
||||
android:layout_gravity="fill_horizontal"
|
||||
/>
|
||||
|
||||
</GridLayout>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user