Response to code review for GridLayout:

. Fixed spelling.
. Added comments on internal methods.
. Adopted the suggested internal name changes to improve clarity.
. Added UNDEFINED constant to public API to avoid making reference to Integer.MAX_VALUE in docs.
. Added final everywhere, then removed it.
. Make the Interval class package private so that it can be put somewhere more general later.
. Tidy code, removing maximize flag throughout.
. Remove last of allocations taking place during layout.
. Implement measureChild() etc.
. Added LinearLayout alignment compatibility mode, and made it the default.

Change-Id: I6a4ffa022d97d68138d1903d3830a20278815435
https://android-git.corp.google.com/g/#change,109891
This commit is contained in:
Philip Milne
2011-05-27 18:38:01 -07:00
parent b2450ce105
commit aa616f31fe
10 changed files with 820 additions and 280 deletions

View File

@@ -179,9 +179,9 @@ package android {
public static final class R.attr {
ctor public R.attr();
field public static final int absListViewStyle = 16842858; // 0x101006a
field public static final int accessibilityEventTypes = 16843645; // 0x101037d
field public static final int accessibilityFeedbackType = 16843647; // 0x101037f
field public static final int accessibilityFlags = 16843649; // 0x1010381
field public static final int accessibilityEventTypes = 16843646; // 0x101037e
field public static final int accessibilityFeedbackType = 16843648; // 0x1010380
field public static final int accessibilityFlags = 16843650; // 0x1010382
field public static final int accountPreferences = 16843423; // 0x101029f
field public static final int accountType = 16843407; // 0x101028f
field public static final int action = 16842797; // 0x101002d
@@ -201,7 +201,7 @@ package android {
field public static final int actionModeCopyDrawable = 16843538; // 0x1010312
field public static final int actionModeCutDrawable = 16843537; // 0x1010311
field public static final int actionModePasteDrawable = 16843539; // 0x1010313
field public static final int actionModeSelectAllDrawable = 16843643; // 0x101037b
field public static final int actionModeSelectAllDrawable = 16843644; // 0x101037c
field public static final int actionOverflowButtonStyle = 16843510; // 0x10102f6
field public static final int actionViewClass = 16843516; // 0x10102fc
field public static final int activatedBackgroundIndicator = 16843517; // 0x10102fd
@@ -273,7 +273,7 @@ package android {
field public static final int cacheColorHint = 16843009; // 0x1010101
field public static final int calendarViewShown = 16843596; // 0x101034c
field public static final int calendarViewStyle = 16843613; // 0x101035d
field public static final int canRetrieveWindowContent = 16843650; // 0x1010382
field public static final int canRetrieveWindowContent = 16843651; // 0x1010383
field public static final int candidatesTextStyleSpans = 16843312; // 0x1010230
field public static final deprecated int capitalize = 16843113; // 0x1010169
field public static final int centerBright = 16842956; // 0x10100cc
@@ -532,7 +532,7 @@ package android {
field public static final int installLocation = 16843447; // 0x10102b7
field public static final int interpolator = 16843073; // 0x1010141
field public static final int isAlwaysSyncable = 16843571; // 0x1010333
field public static final int isAuxiliary = 16843644; // 0x101037c
field public static final int isAuxiliary = 16843645; // 0x101037d
field public static final int isDefault = 16843297; // 0x1010221
field public static final int isIndicator = 16843079; // 0x1010147
field public static final int isModifier = 16843334; // 0x1010246
@@ -584,8 +584,8 @@ package android {
field public static final int layout_centerInParent = 16843151; // 0x101018f
field public static final int layout_centerVertical = 16843153; // 0x1010191
field public static final int layout_column = 16843084; // 0x101014c
field public static final int layout_columnSpan = 16843641; // 0x1010379
field public static final int layout_columnWeight = 16843642; // 0x101037a
field public static final int layout_columnSpan = 16843642; // 0x101037a
field public static final int layout_columnWeight = 16843643; // 0x101037b
field public static final int layout_gravity = 16842931; // 0x10100b3
field public static final int layout_height = 16842997; // 0x10100f5
field public static final int layout_margin = 16842998; // 0x10100f6
@@ -593,9 +593,9 @@ package android {
field public static final int layout_marginLeft = 16842999; // 0x10100f7
field public static final int layout_marginRight = 16843001; // 0x10100f9
field public static final int layout_marginTop = 16843000; // 0x10100f8
field public static final int layout_row = 16843638; // 0x1010376
field public static final int layout_rowSpan = 16843639; // 0x1010377
field public static final int layout_rowWeight = 16843640; // 0x1010378
field public static final int layout_row = 16843639; // 0x1010377
field public static final int layout_rowSpan = 16843640; // 0x1010378
field public static final int layout_rowWeight = 16843641; // 0x1010379
field public static final int layout_scale = 16843155; // 0x1010193
field public static final int layout_span = 16843085; // 0x101014d
field public static final int layout_toLeftOf = 16843138; // 0x1010182
@@ -625,6 +625,7 @@ package android {
field public static final int loopViews = 16843527; // 0x1010307
field public static final int manageSpaceActivity = 16842756; // 0x1010004
field public static final int mapViewStyle = 16842890; // 0x101008a
field public static final int marginsIncludedInAlignment = 16843638; // 0x1010376
field public static final int marqueeRepeatLimit = 16843293; // 0x101021d
field public static final int max = 16843062; // 0x1010136
field public static final int maxDate = 16843584; // 0x1010340
@@ -661,7 +662,7 @@ package android {
field public static final int nextFocusUp = 16842979; // 0x10100e3
field public static final int noHistory = 16843309; // 0x101022d
field public static final int normalScreens = 16843397; // 0x1010285
field public static final int notificationTimeout = 16843648; // 0x1010380
field public static final int notificationTimeout = 16843649; // 0x1010381
field public static final int numColumns = 16843032; // 0x1010118
field public static final int numStars = 16843076; // 0x1010144
field public static final deprecated int numeric = 16843109; // 0x1010165
@@ -678,7 +679,7 @@ package android {
field public static final int overScrollFooter = 16843459; // 0x10102c3
field public static final int overScrollHeader = 16843458; // 0x10102c2
field public static final int overScrollMode = 16843457; // 0x10102c1
field public static final int packageNames = 16843646; // 0x101037e
field public static final int packageNames = 16843647; // 0x101037f
field public static final int padding = 16842965; // 0x10100d5
field public static final int paddingBottom = 16842969; // 0x10100d9
field public static final int paddingLeft = 16842966; // 0x10100d6
@@ -24533,6 +24534,7 @@ package android.widget {
ctor public GridLayout(android.content.Context, android.util.AttributeSet, int);
ctor public GridLayout(android.content.Context, android.util.AttributeSet);
method public int getColumnCount();
method public boolean getMarginsIncludedInAlignment();
method public int getOrientation();
method public int getRowCount();
method public boolean getUseDefaultMargins();
@@ -24541,6 +24543,7 @@ package android.widget {
method protected void onLayout(boolean, int, int, int, int);
method public void setColumnCount(int);
method public void setColumnOrderPreserved(boolean);
method public void setMarginsIncludedInAlignment(boolean);
method public void setOrientation(int);
method public void setRowCount(int);
method public void setRowOrderPreserved(boolean);
@@ -24553,6 +24556,7 @@ package android.widget {
field public static final android.widget.GridLayout.Alignment LEFT;
field public static final android.widget.GridLayout.Alignment RIGHT;
field public static final android.widget.GridLayout.Alignment TOP;
field public static final int UNDEFINED = -2147483648; // 0x80000000
field public static final int VERTICAL = 1; // 0x1
}
@@ -24562,17 +24566,9 @@ package android.widget {
}
public static class GridLayout.Group {
ctor public GridLayout.Group(android.widget.GridLayout.Interval, android.widget.GridLayout.Alignment);
ctor public GridLayout.Group(int, int, android.widget.GridLayout.Alignment);
ctor public GridLayout.Group(int, android.widget.GridLayout.Alignment);
field public final android.widget.GridLayout.Alignment alignment;
field public final android.widget.GridLayout.Interval span;
}
public static class GridLayout.Interval {
ctor public GridLayout.Interval(int, int);
field public final int max;
field public final int min;
}
public static class GridLayout.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {

File diff suppressed because it is too large Load Diff

View File

@@ -2522,10 +2522,10 @@
</declare-styleable>
<declare-styleable name="GridLayout">
<!-- The orientation property is not used during layout. It is only used to
allocate row and column prameters when they are not specified by its children's
allocate row and column parameters when they are not specified by its children's
layout paramters. GridLayout works like LinearLayout in this case;
putting all the components either in a single row or in a single column -
depending on the value of this flag. In the horozintal case, a columnCount
depending on the value of this flag. In the horizontal case, a columnCount
property may be additionally supplied to force new rows to be created when a
row is full. The rowCount attribute may be used similarly in the vertical case.
The default is horizontal. -->
@@ -2539,6 +2539,12 @@
The default value is false.
See {@link android.widget.GridLayout#setUseDefaultMargins(boolean)}.-->
<attr name="useDefaultMargins" format="boolean" />
<!-- When set to true, causes alignment to take place between the outer
boundary of a view, as defined by its margins. When set to false,
causes alignment to take place between the edges of the view.
The default is true.
See {@link android.widget.GridLayout#setMarginsIncludedInAlignment(boolean)}.-->
<attr name="marginsIncludedInAlignment" format="boolean" />
<!-- When set to true, forces row boundaries to appear in the same order
as row indices.
The default is false.
@@ -3256,9 +3262,9 @@
<!-- The row span: the difference between the bottom and top
boundaries delimiting the group of cells occupied by this view.
The default is one.
See {@link android.widget.GridLayout.Group#span}. -->
See {@link android.widget.GridLayout.Group}. -->
<attr name="layout_rowSpan" format="integer" min="1" />
<!-- A number indicating the relative proportion of availible space that
<!-- A number indicating the relative proportion of available space that
should be taken by this group of cells.
The default is zero.
See {@link android.widget.GridLayout.LayoutParams#columnWeight}. -->
@@ -3269,9 +3275,9 @@
<!-- The column span: the difference between the right and left
boundaries delimiting the group of cells occupied by this view.
The default is one.
See {@link android.widget.GridLayout.Group#span}. -->
See {@link android.widget.GridLayout.Group}. -->
<attr name="layout_columnSpan" format="integer" min="1" />
<!-- A number indicating the relative proportion of availible space that
<!-- A number indicating the relative proportion of available space that
should be taken by this group of cells.
The default is zero.
See {@link android.widget.GridLayout.LayoutParams#columnWeight}.-->

View File

@@ -1684,6 +1684,7 @@
<public type="attr" name="columnCount" />
<public type="attr" name="columnOrderPreserved" />
<public type="attr" name="useDefaultMargins" />
<public type="attr" name="marginsIncludedInAlignment" />
<public type="attr" name="layout_row" />
<public type="attr" name="layout_rowSpan" />

View File

@@ -76,6 +76,27 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name="AlignmentTest" android:label="AlignmentTest">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name="LinearLayoutTest" android:label="LinearLayoutTest">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name="GridLayoutTest" android:label="GridLayoutTest">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>

View File

@@ -0,0 +1,71 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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;
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 View create(Context context, String name, int size) {
Button result = new Button(context);
result.setText(name);
result.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
animate(v);
}
});
return result;
}
public abstract ViewGroup create(Context context);
public abstract String tag();
public void animate(View v) {
long start = System.currentTimeMillis();
int N = 1000;
for (int i = 0; i < N; i++) {
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
lp.topMargin = (lp.topMargin + 1) % 31;
lp.leftMargin = (lp.leftMargin + 1) % 31;
v.requestLayout();
v.invalidate();
ViewGroup p = (ViewGroup) v.getParent();
p.layout(0, 0, 1000 + (i % 2), 500 + (i % 2));
}
Log.d(tag(), "Time: " + (float) (System.currentTimeMillis() - start) / N * 1000 + "mics");
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(create(getBaseContext()));
}
}

View File

@@ -32,6 +32,7 @@ public class Activity2 extends Activity {
public static View create(Context context) {
GridLayout vg = new GridLayout(context);
vg.setUseDefaultMargins(true);
vg.setMarginsIncludedInAlignment(false);
Group row1 = new Group(1, CENTER);
Group row2 = new Group(2, CENTER);

View File

@@ -0,0 +1,116 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.test.layout;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridLayout;
import android.widget.TextView;
import static android.widget.GridLayout.*;
public class AlignmentTest extends Activity {
public static final String[] HORIZONTAL_NAMES = new String[]{"LEFT", "center", "east", "fill"};
public static final Alignment[] HORIZONTAL_ALIGNMENTS = new Alignment[]{LEFT, CENTER, RIGHT, FILL};
public static final String[] VERTICAL_NAMES = new String[]{"north", "center", "baseline", "south", "fill"};
public static final Alignment[] VERTICAL_ALIGNMENTS = new Alignment[]{TOP, CENTER, BASELINE, BOTTOM, FILL};
private static Context CONTEXT;
public static interface ViewFactory {
View create(String name, int size);
}
public static final ViewFactory BUTTON_FACTORY = new ViewFactory() {
public View create(String name, int size) {
Button result = new Button(CONTEXT);
result.setText(name);
result.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
animate(v);
}
});
return result;
}
};
public static final ViewFactory LABEL_FACTORY = new ViewFactory() {
public View create(String name, int size) {
TextView result = new TextView(CONTEXT);
result.setText(name);
result.setTextSize(40);
return result;
}
};
public static final ViewFactory TEXT_FIELD_FACTORY = new ViewFactory() {
public View create(String name, int size) {
EditText result = new EditText(CONTEXT);
result.setText(name);
return result;
}
};
public static final ViewFactory[] FACTORIES = new ViewFactory[]{BUTTON_FACTORY, LABEL_FACTORY, TEXT_FIELD_FACTORY};
public static ViewGroup create(Context context1) {
CONTEXT = context1;
GridLayout container = new GridLayout(context1);
container.setUseDefaultMargins(true);
for (int i = 0; i < VERTICAL_ALIGNMENTS.length; i++) {
Alignment va = VERTICAL_ALIGNMENTS[i];
for (int j = 0; j < HORIZONTAL_ALIGNMENTS.length; j++) {
Alignment ha = HORIZONTAL_ALIGNMENTS[j];
Group rowGroup = new Group(i, va);
Group colGroup = new Group(j, ha);
LayoutParams layoutParams = new LayoutParams(rowGroup, colGroup);
container.addView(FACTORIES[(i + j) % FACTORIES.length].create(VERTICAL_NAMES[i] + "-" + HORIZONTAL_NAMES[j], 20), layoutParams);
}
}
return container;
}
public static void animate(View v) {
long start = System.currentTimeMillis();
int N = 1000;
for (int i = 0; i < N; i++) {
ViewGroup.LayoutParams lp = v.getLayoutParams();
lp.width += 1; // width;
lp.height += 1; // height;
v.requestLayout();
GridLayout p = (GridLayout) v.getParent();
p.layout(0, 0, 1000 + (i % 2), 500 + (i % 2));
}
System.out.println("Time: " + (float) (System.currentTimeMillis() - start) / N * 1000 + "mics");
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(create(getBaseContext()));
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.test.layout;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.GridLayout;
import static android.widget.GridLayout.*;
public class GridLayoutTest extends AbstractLayoutTest {
public ViewGroup create(Context context) {
GridLayout container = new GridLayout(context);
container.setOrientation(VERTICAL);
// container.setUseDefaultMargins(true);
for (int i = 0; i < VERTICAL_ALIGNMENTS.length; i++) {
int va = VERTICAL_ALIGNMENTS[i];
for (int j = 0; j < HORIZONTAL_ALIGNMENTS.length; j++) {
int ha = HORIZONTAL_ALIGNMENTS[j];
GridLayout.Group rowGroup = new GridLayout.Group(UNDEFINED, null);
GridLayout.Group colGroup = new GridLayout.Group(UNDEFINED, null);
GridLayout.LayoutParams lp = new GridLayout.LayoutParams(rowGroup, colGroup);
lp.setGravity(va | ha);
// View v = create(VERTICAL_NAMES[i] + "-" + HORIZONTAL_NAMES[j], 20);
View v = create(context, VERTICAL_NAMES[i] + "-" + HORIZONTAL_NAMES[j], 20);
container.addView(v, lp);
}
}
return container;
}
public String tag() {
return GridLayoutTest.class.getName();
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.test.layout;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import static android.widget.LinearLayout.*;
public class LinearLayoutTest extends AbstractLayoutTest {
public ViewGroup create(Context context) {
LinearLayout container = new LinearLayout(context);
container.setOrientation(LinearLayout.VERTICAL);
// container.setUseDefaultMargins(true);
for (int i = 0; i < VERTICAL_ALIGNMENTS.length; i++) {
int va = VERTICAL_ALIGNMENTS[i];
for (int j = 0; j < HORIZONTAL_ALIGNMENTS.length; j++) {
int ha = HORIZONTAL_ALIGNMENTS[j];
LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.gravity = va | ha;
// View v = create(VERTICAL_NAMES[i] + "-" + HORIZONTAL_NAMES[j], 20);
View v = create(context, VERTICAL_NAMES[i] + "-" + HORIZONTAL_NAMES[j], 20);
container.addView(v, lp);
}
}
return container;
}
public String tag() {
return LinearLayoutTest.class.getName();
}
}