summaryrefslogtreecommitdiffstats
path: root/core/java/android/widget
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/widget')
-rw-r--r--core/java/android/widget/GridLayout.java182
1 files changed, 104 insertions, 78 deletions
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java
index 7c0470e..c2759e5 100644
--- a/core/java/android/widget/GridLayout.java
+++ b/core/java/android/widget/GridLayout.java
@@ -92,10 +92,8 @@ import static java.lang.Math.min;
*
* <h4>Excess Space Distribution</h4>
*
- * Like {@link LinearLayout}, a child's ability to stretch is controlled
- * using <em>weights</em>, which are specified using the
- * {@link GridLayout.LayoutParams#widthSpec widthSpec} and
- * {@link GridLayout.LayoutParams#heightSpec heightSpec} layout parameters.
+ * A child's ability to stretch is controlled using the {@link Group#flexibility flexibility}
+ * properties of its row and column groups.
* <p>
* <p>
* See {@link GridLayout.LayoutParams} for a full description of the
@@ -1055,7 +1053,7 @@ public class GridLayout extends ViewGroup {
if (isGone(c)) continue;
LayoutParams lp = getLayoutParams(c);
Group g = horizontal ? lp.columnGroup : lp.rowGroup;
- groupBounds.getValue(i).include(c, g, GridLayout.this, this, lp);
+ groupBounds.getValue(i).include(c, g, GridLayout.this, this);
}
}
@@ -1087,13 +1085,17 @@ public class GridLayout extends ViewGroup {
spans[i].reset();
}
- // use getter to trigger a re-evaluation
+ // Use getter to trigger a re-evaluation
Bounds[] bounds = getGroupBounds().values;
for (int i = 0; i < bounds.length; i++) {
int size = bounds[i].size(min);
- int value = min ? size : -size;
MutableInt valueHolder = links.getValue(i);
- valueHolder.value = max(valueHolder.value, value);
+ if (min) {
+ valueHolder.value = max(valueHolder.value, size);
+ }
+ else {
+ valueHolder.value = -max(-valueHolder.value, size);
+ }
}
}
@@ -1155,7 +1157,7 @@ public class GridLayout extends ViewGroup {
int[] sizes = new int[N];
for (Arc arc : arcs) {
sizes[arc.span.min]++;
- }
+ }
for (int i = 0; i < sizes.length; i++) {
result[i] = new Arc[sizes[i]];
}
@@ -1622,16 +1624,14 @@ public class GridLayout extends ViewGroup {
* <li>{@link #rowGroup}{@code .alignment} = {@link #BASELINE} </li>
* <li>{@link #columnGroup}{@code .span} = {@code [0, 1]} </li>
* <li>{@link #columnGroup}{@code .alignment} = {@link #LEFT} </li>
- * <li>{@link #widthSpec} = {@link #FIXED} </li>
- * <li>{@link #heightSpec} = {@link #FIXED} </li>
* </ul>
*
* @attr ref android.R.styleable#GridLayout_Layout_layout_row
* @attr ref android.R.styleable#GridLayout_Layout_layout_rowSpan
- * @attr ref android.R.styleable#GridLayout_Layout_layout_heightSpec
+ * @attr ref android.R.styleable#GridLayout_Layout_layout_rowFlexibility
* @attr ref android.R.styleable#GridLayout_Layout_layout_column
* @attr ref android.R.styleable#GridLayout_Layout_layout_columnSpan
- * @attr ref android.R.styleable#GridLayout_Layout_layout_widthSpec
+ * @attr ref android.R.styleable#GridLayout_Layout_layout_columnFlexibility
* @attr ref android.R.styleable#GridLayout_Layout_layout_gravity
*/
public static class LayoutParams extends MarginLayoutParams {
@@ -1647,19 +1647,12 @@ public class GridLayout extends ViewGroup {
private static final int DEFAULT_SPAN_SIZE = DEFAULT_SPAN.size();
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 Spec DEFAULT_SPEC = FIXED;
- private static final int DEFAULT_SPEC_INDEX = 0;
// Misc
private static final Rect CONTAINER_BOUNDS = new Rect(0, 0, 2, 2);
private static final Alignment[] COLUMN_ALIGNMENTS = { LEFT, CENTER, RIGHT };
private static final Alignment[] ROW_ALIGNMENTS = { TOP, CENTER, BOTTOM };
- private static final Spec[] SPECS = { FIXED, CAN_SHRINK, CAN_STRETCH };
// TypedArray indices
@@ -1672,10 +1665,14 @@ public class GridLayout extends ViewGroup {
private static final int COLUMN = styleable.GridLayout_Layout_layout_column;
private static final int COLUMN_SPAN = styleable.GridLayout_Layout_layout_columnSpan;
- private static final int WIDTH_SPEC = styleable.GridLayout_Layout_layout_widthSpec;
+ private static final int COLUMN_FLEXIBILITY =
+ styleable.GridLayout_Layout_layout_columnFlexibility;
+
private static final int ROW = styleable.GridLayout_Layout_layout_row;
private static final int ROW_SPAN = styleable.GridLayout_Layout_layout_rowSpan;
- private static final int HEIGHT_SPEC = styleable.GridLayout_Layout_layout_heightSpec;
+ private static final int ROW_FLEXIBILITY =
+ styleable.GridLayout_Layout_layout_rowFlexibility;
+
private static final int GRAVITY = styleable.GridLayout_Layout_layout_gravity;
// Instance variables
@@ -1690,30 +1687,17 @@ public class GridLayout extends ViewGroup {
* described by these layout parameters.
*/
public Group columnGroup;
- /**
- * The proportional space that should be taken by the associated column group
- * during excess space distribution.
- */
- public Spec widthSpec;
- /**
- * The proportional space that should be taken by the associated row group
- * during excess space distribution.
- */
- public Spec heightSpec;
// Constructors
private LayoutParams(
int width, int height,
int left, int top, int right, int bottom,
- Group rowGroup, Group columnGroup,
- Spec widthSpec, Spec heightSpec) {
+ Group rowGroup, Group columnGroup) {
super(width, height);
setMargins(left, top, right, bottom);
this.rowGroup = rowGroup;
this.columnGroup = columnGroup;
- this.heightSpec = heightSpec;
- this.widthSpec = widthSpec;
}
/**
@@ -1727,14 +1711,15 @@ public class GridLayout extends ViewGroup {
public LayoutParams(Group rowGroup, Group columnGroup) {
this(DEFAULT_WIDTH, DEFAULT_HEIGHT,
DEFAULT_MARGIN, DEFAULT_MARGIN, DEFAULT_MARGIN, DEFAULT_MARGIN,
- rowGroup, columnGroup, DEFAULT_SPEC, DEFAULT_SPEC);
+ rowGroup, columnGroup);
}
/**
* Constructs a new LayoutParams with default values as defined in {@link LayoutParams}.
*/
public LayoutParams() {
- this(DEFAULT_ROW_GROUP, DEFAULT_COLUMN_GROUP);
+ this(new Group(DEFAULT_SPAN, DEFAULT_ROW_ALIGNMENT),
+ new Group(DEFAULT_SPAN, DEFAULT_COLUMN_ALIGNMENT));
}
// Copying constructors
@@ -1758,10 +1743,8 @@ public class GridLayout extends ViewGroup {
*/
public LayoutParams(LayoutParams that) {
super(that);
- this.columnGroup = that.columnGroup;
- this.rowGroup = that.rowGroup;
- this.widthSpec = that.widthSpec;
- this.heightSpec = that.heightSpec;
+ this.columnGroup = new Group(that.columnGroup);
+ this.rowGroup = new Group(that.rowGroup);
}
// AttributeSet constructors
@@ -1825,7 +1808,7 @@ 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 getColumnAlignment(int gravity, int width) {
+ private static Alignment getColAlignment(int gravity, int width) {
Rect r = new Rect(0, 0, 0, 0);
Gravity.apply(gravity, 0, 0, CONTAINER_BOUNDS, r);
@@ -1853,14 +1836,14 @@ public class GridLayout extends ViewGroup {
int column = a.getInt(COLUMN, DEFAULT_COLUMN);
int columnSpan = a.getInt(COLUMN_SPAN, DEFAULT_SPAN_SIZE);
Interval hSpan = new Interval(column, column + columnSpan);
- this.columnGroup = new Group(hSpan, getColumnAlignment(gravity, width));
- this.widthSpec = SPECS[a.getInt(WIDTH_SPEC, DEFAULT_SPEC_INDEX)];
+ int hFlexibility = a.getInt(COLUMN_FLEXIBILITY, Group.DEFAULT_FLEXIBILITY);
+ this.columnGroup = new Group(hSpan, getColAlignment(gravity, width), hFlexibility);
int row = a.getInt(ROW, DEFAULT_ROW);
int rowSpan = a.getInt(ROW_SPAN, DEFAULT_SPAN_SIZE);
Interval vSpan = new Interval(row, row + rowSpan);
- this.rowGroup = new Group(vSpan, getRowAlignment(gravity, height));
- this.heightSpec = SPECS[a.getInt(HEIGHT_SPEC, DEFAULT_SPEC_INDEX)];
+ int vFlexibility = a.getInt(ROW_FLEXIBILITY, Group.DEFAULT_FLEXIBILITY);
+ this.rowGroup = new Group(vSpan, getRowAlignment(gravity, height), vFlexibility);
} finally {
a.recycle();
}
@@ -1875,7 +1858,7 @@ public class GridLayout extends ViewGroup {
* @attr ref android.R.styleable#GridLayout_Layout_layout_gravity
*/
public void setGravity(int gravity) {
- columnGroup = columnGroup.copyWriteAlignment(getColumnAlignment(gravity, width));
+ columnGroup = columnGroup.copyWriteAlignment(getColAlignment(gravity, width));
rowGroup = rowGroup.copyWriteAlignment(getRowAlignment(gravity, height));
}
@@ -2051,7 +2034,7 @@ public class GridLayout extends ViewGroup {
public int before;
public int after;
- public boolean canStretch;
+ public int flexibility;
private Bounds() {
reset();
@@ -2060,7 +2043,7 @@ public class GridLayout extends ViewGroup {
protected void reset() {
before = Integer.MIN_VALUE;
after = Integer.MIN_VALUE;
- canStretch = false;
+ flexibility = UNDEFINED_FLEXIBILITY;
}
protected void include(int before, int after) {
@@ -2069,8 +2052,13 @@ public class GridLayout extends ViewGroup {
}
protected int size(boolean min) {
- if (!min && canStretch) {
- return MAX_SIZE;
+ if (!min) {
+ // Note in the usual case, components don't define anything
+ // leaving their flexibility is undefined and their stretchability
+ // defined as if the CAN_STRETCH flag was false.
+ if (canStretch(flexibility) && !isUndefined(flexibility)) {
+ return MAX_SIZE;
+ }
}
return before + after;
}
@@ -2079,14 +2067,11 @@ public class GridLayout extends ViewGroup {
return before - alignment.getAlignmentValue(c, size);
}
- protected void include(View c, Group g, GridLayout gridLayout, Axis axis, LayoutParams lp) {
- Spec spec = axis.horizontal ? lp.widthSpec : lp.heightSpec;
- if (spec == CAN_STRETCH) {
- canStretch = true;
- }
+ protected void include(View c, Group group, GridLayout gridLayout, Axis axis) {
+ this.flexibility &= group.flexibility;
int size = gridLayout.getMeasurementIncludingMargin(c, axis.horizontal);
// todo test this works correctly when the returned value is UNDEFINED
- int before = g.alignment.getAlignmentValue(c, size);
+ int before = group.alignment.getAlignmentValue(c, size);
include(before, size - before);
}
@@ -2198,6 +2183,8 @@ public class GridLayout extends ViewGroup {
* {@code span} and {@code alignment}.
*/
public static class Group {
+ private static final int DEFAULT_FLEXIBILITY = UNDEFINED_FLEXIBILITY;
+
private static final Group GONE = new Group(Interval.GONE, Alignment.GONE);
/**
@@ -2216,6 +2203,18 @@ public class GridLayout extends ViewGroup {
public final Alignment alignment;
/**
+ * The flexibility field tells GridLayout how to derive minimum and maximum size
+ * values for a component. Specifications are made with respect to a child's
+ * 'measured size'. A child's measured size is, in turn, controlled by its
+ * height and width layout parameters which either specify a size or, in
+ * the case of {@link LayoutParams#WRAP_CONTENT WRAP_CONTENT}, defer to
+ * the computed size of the component.
+ *
+ * @see GridLayout#CAN_STRETCH
+ */
+ public int flexibility = DEFAULT_FLEXIBILITY;
+
+ /**
* Construct a new Group, {@code group}, where:
* <ul>
* <li> {@code group.span = span} </li>
@@ -2225,9 +2224,22 @@ public class GridLayout extends ViewGroup {
* @param span the span
* @param alignment the alignment
*/
- Group(Interval span, Alignment alignment) {
+ private Group(Interval span, Alignment alignment) {
+ this.span = span;
+ this.alignment = alignment;
+ }
+
+ private Group(Interval span, Alignment alignment, int flexibility) {
this.span = span;
this.alignment = alignment;
+ this.flexibility = flexibility;
+ }
+
+ /* Copying constructor */
+ private Group(Group that) {
+ this.span = that.span;
+ this.alignment = that.alignment;
+ this.flexibility = that.flexibility;
}
/**
@@ -2260,11 +2272,11 @@ public class GridLayout extends ViewGroup {
}
private Group copyWriteSpan(Interval span) {
- return new Group(span, alignment);
+ return new Group(span, alignment, flexibility);
}
private Group copyWriteAlignment(Alignment alignment) {
- return new Group(span, alignment);
+ return new Group(span, alignment, flexibility);
}
/**
@@ -2490,40 +2502,54 @@ public class GridLayout extends ViewGroup {
}
};
- /**
- * Spec's tell GridLayout how to derive minimum and maximum size values for a
- * component. Specifications are made with respect to a child's 'measured size'.
- * A child's measured size is, in turn, controlled by its height and width
- * layout parameters which either specify a size or, in the case of
- * WRAP_CONTENT, defer to the computed size of the component.
- */
- public static abstract class Spec {
+ private static boolean canStretch(int flexibility) {
+ return (flexibility & CAN_STRETCH) != 0;
+ }
+
+ private static boolean isUndefined(int flexibility) {
+ return (flexibility & UNDEFINED) != 0;
}
/**
* Indicates that a view requests precisely the size specified by its layout parameters.
*
- * @see Spec
+ * @see Group#flexibility
+ *
+ * @hide
*/
- public static final Spec FIXED = new Spec() {
- };
+ public static final int FIXED = 0;
/**
* Indicates that a view's size should lie between its minimum and the size specified by
* its layout parameters.
*
- * @see Spec
+ * @see Group#flexibility
+ *
+ * @hide
*/
- public static final Spec CAN_SHRINK = new Spec() {
- };
+ public static final int CAN_SHRINK = 1;
/**
* Indicates that a view's size should be greater than or equal to the size specified by
* its layout parameters.
*
- * @see Spec
+ * @see Group#flexibility
*/
- public static final Spec CAN_STRETCH = new Spec() {
- };
+ public static final int CAN_STRETCH = 2;
+
+ /**
+ * Indicates that a view will ignore its measurement, and can take any size that is greater
+ * than its minimum.
+ *
+ * @see Group#flexibility
+ */
+ private static final int CAN_SHRINK_OR_STRETCH = CAN_SHRINK | CAN_STRETCH;
+
+ /**
+ * A default value for flexibility.
+ *
+ * @see Group#flexibility
+ */
+ private static final int UNDEFINED_FLEXIBILITY = UNDEFINED | CAN_SHRINK | CAN_STRETCH;
}