Skip to content

Commit 94355ed

Browse files
Philip MilneAndroid (Google) Code Review
authored andcommitted
Merge "New hooks to allow layouts to improve their performance by doing more caching"
2 parents 5e264cc + d7dd890 commit 94355ed

File tree

3 files changed

+93
-19
lines changed

3 files changed

+93
-19
lines changed

core/java/android/view/View.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8252,6 +8252,9 @@ public void setLayoutParams(ViewGroup.LayoutParams params) {
82528252
throw new NullPointerException("Layout parameters cannot be null");
82538253
}
82548254
mLayoutParams = params;
8255+
if (mParent instanceof ViewGroup) {
8256+
((ViewGroup) mParent).onSetLayoutParams(this, params);
8257+
}
82558258
requestLayout();
82568259
}
82578260

core/java/android/view/ViewGroup.java

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5203,6 +5203,10 @@ public boolean shouldDelayChildPressedState() {
52035203
return true;
52045204
}
52055205

5206+
/** @hide */
5207+
protected void onSetLayoutParams(View child, LayoutParams layoutParams) {
5208+
}
5209+
52065210
/**
52075211
* LayoutParams are used by views to tell their parents how they want to be
52085212
* laid out. See
@@ -5411,29 +5415,33 @@ protected static String sizeToString(int size) {
54115415
*/
54125416
public static class MarginLayoutParams extends ViewGroup.LayoutParams {
54135417
/**
5414-
* The left margin in pixels of the child. Whenever this value is changed, a call to
5415-
* {@link android.view.View#requestLayout()} needs to be done.
5418+
* The left margin in pixels of the child.
5419+
* Call {@link ViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value
5420+
* to this field.
54165421
*/
54175422
@ViewDebug.ExportedProperty(category = "layout")
54185423
public int leftMargin;
54195424

54205425
/**
5421-
* The top margin in pixels of the child. Whenever this value is changed, a call to
5422-
* {@link android.view.View#requestLayout()} needs to be done.
5426+
* The top margin in pixels of the child.
5427+
* Call {@link ViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value
5428+
* to this field.
54235429
*/
54245430
@ViewDebug.ExportedProperty(category = "layout")
54255431
public int topMargin;
54265432

54275433
/**
5428-
* The right margin in pixels of the child. Whenever this value is changed, a call to
5429-
* {@link android.view.View#requestLayout()} needs to be done.
5434+
* The right margin in pixels of the child.
5435+
* Call {@link ViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value
5436+
* to this field.
54305437
*/
54315438
@ViewDebug.ExportedProperty(category = "layout")
54325439
public int rightMargin;
54335440

54345441
/**
5435-
* The bottom margin in pixels of the child. Whenever this value is changed, a call to
5436-
* {@link android.view.View#requestLayout()} needs to be done.
5442+
* The bottom margin in pixels of the child.
5443+
* Call {@link ViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value
5444+
* to this field.
54375445
*/
54385446
@ViewDebug.ExportedProperty(category = "layout")
54395447
public int bottomMargin;

core/java/android/widget/GridLayout.java

Lines changed: 74 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ public class GridLayout extends ViewGroup {
212212
static final int PRF = 1;
213213
static final int MAX_SIZE = 100000;
214214
static final int DEFAULT_CONTAINER_MARGIN = 0;
215+
static final int UNINITIALIZED_HASH = 0;
215216

216217
// Defaults
217218

@@ -240,6 +241,7 @@ public class GridLayout extends ViewGroup {
240241
boolean useDefaultMargins = DEFAULT_USE_DEFAULT_MARGINS;
241242
int alignmentMode = DEFAULT_ALIGNMENT_MODE;
242243
int defaultGap;
244+
int lastLayoutParamsHashCode = UNINITIALIZED_HASH;
243245

244246
// Constructors
245247

@@ -668,7 +670,7 @@ private void validateLayoutParams() {
668670
int[] maxSizes = new int[count];
669671

670672
for (int i = 0, N = getChildCount(); i < N; i++) {
671-
LayoutParams lp = getLayoutParams1(getChildAt(i));
673+
LayoutParams lp = (LayoutParams) getChildAt(i).getLayoutParams();
672674

673675
final Spec majorSpec = horizontal ? lp.rowSpec : lp.columnSpec;
674676
final Interval majorRange = majorSpec.span;
@@ -713,6 +715,7 @@ private void validateLayoutParams() {
713715

714716
minor = minor + minorSpan;
715717
}
718+
lastLayoutParamsHashCode = computeLayoutParamsHashCode();
716719
invalidateStructure();
717720
}
718721

@@ -733,16 +736,19 @@ private void invalidateValues() {
733736
}
734737
}
735738

736-
private LayoutParams getLayoutParams1(View c) {
737-
return (LayoutParams) c.getLayoutParams();
739+
/** @hide */
740+
@Override
741+
protected void onSetLayoutParams(View child, ViewGroup.LayoutParams layoutParams) {
742+
super.onSetLayoutParams(child, layoutParams);
743+
invalidateStructure();
738744
}
739745

740746
final LayoutParams getLayoutParams(View c) {
741747
if (!layoutParamsValid) {
742748
validateLayoutParams();
743749
layoutParamsValid = true;
744750
}
745-
return getLayoutParams1(c);
751+
return (LayoutParams) c.getLayoutParams();
746752
}
747753

748754
@Override
@@ -859,12 +865,29 @@ protected void onChildVisibilityChanged(View child, int oldVisibility, int newVi
859865
}
860866
}
861867

862-
// Measurement
868+
private int computeLayoutParamsHashCode() {
869+
int result = 1;
870+
for (int i = 0, N = getChildCount(); i < N; i++) {
871+
View c = getChildAt(i);
872+
if (c.getVisibility() == View.GONE) continue;
873+
LayoutParams lp = (LayoutParams) c.getLayoutParams();
874+
result = 31 * result + lp.hashCode();
875+
}
876+
return result;
877+
}
863878

864-
final boolean isGone(View c) {
865-
return c.getVisibility() == View.GONE;
879+
private void checkForLayoutParamsModification() {
880+
int layoutParamsHashCode = computeLayoutParamsHashCode();
881+
if (lastLayoutParamsHashCode != UNINITIALIZED_HASH &&
882+
lastLayoutParamsHashCode != layoutParamsHashCode) {
883+
invalidateStructure();
884+
Log.w(TAG, "The fields of some layout parameters were modified in between layout " +
885+
"operations. Check the javadoc for GridLayout.LayoutParams#rowSpec.");
886+
}
866887
}
867888

889+
// Measurement
890+
868891
private void measureChildWithMargins2(View child, int parentWidthSpec, int parentHeightSpec,
869892
int childWidth, int childHeight) {
870893
int childWidthSpec = getChildMeasureSpec(parentWidthSpec,
@@ -877,7 +900,7 @@ private void measureChildWithMargins2(View child, int parentWidthSpec, int paren
877900
private void measureChildrenWithMargins(int widthSpec, int heightSpec, boolean firstPass) {
878901
for (int i = 0, N = getChildCount(); i < N; i++) {
879902
View c = getChildAt(i);
880-
if (isGone(c)) continue;
903+
if (c.getVisibility() == View.GONE) continue;
881904
LayoutParams lp = getLayoutParams(c);
882905
if (firstPass) {
883906
measureChildWithMargins2(c, widthSpec, heightSpec, lp.width, lp.height);
@@ -902,6 +925,8 @@ private void measureChildrenWithMargins(int widthSpec, int heightSpec, boolean f
902925

903926
@Override
904927
protected void onMeasure(int widthSpec, int heightSpec) {
928+
checkForLayoutParamsModification();
929+
905930
/** If we have been called by {@link View#measure(int, int)}, one of width or height
906931
* is likely to have changed. We must invalidate if so. */
907932
invalidateValues();
@@ -941,7 +966,7 @@ private int getMeasurement(View c, boolean horizontal) {
941966
}
942967

943968
final int getMeasurementIncludingMargin(View c, boolean horizontal) {
944-
if (isGone(c)) {
969+
if (c.getVisibility() == View.GONE) {
945970
return 0;
946971
}
947972
return getMeasurement(c, horizontal) + getTotalMargin(c, horizontal);
@@ -974,6 +999,8 @@ the grid (respectively!).
974999
*/
9751000
@Override
9761001
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
1002+
checkForLayoutParamsModification();
1003+
9771004
int targetWidth = right - left;
9781005
int targetHeight = bottom - top;
9791006

@@ -990,7 +1017,7 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto
9901017

9911018
for (int i = 0, N = getChildCount(); i < N; i++) {
9921019
View c = getChildAt(i);
993-
if (isGone(c)) continue;
1020+
if (c.getVisibility() == View.GONE) continue;
9941021
LayoutParams lp = getLayoutParams(c);
9951022
Spec columnSpec = lp.columnSpec;
9961023
Spec rowSpec = lp.rowSpec;
@@ -1527,7 +1554,7 @@ private void computeMargins(boolean leading) {
15271554
int[] margins = leading ? leadingMargins : trailingMargins;
15281555
for (int i = 0, N = getChildCount(); i < N; i++) {
15291556
View c = getChildAt(i);
1530-
if (isGone(c)) continue;
1557+
if (c.getVisibility() == View.GONE) continue;
15311558
LayoutParams lp = getLayoutParams(c);
15321559
Spec spec = horizontal ? lp.columnSpec : lp.rowSpec;
15331560
Interval span = spec.span;
@@ -1767,12 +1794,28 @@ public static class LayoutParams extends MarginLayoutParams {
17671794
/**
17681795
* The spec that defines the vertical characteristics of the cell group
17691796
* described by these layout parameters.
1797+
* If an assignment is made to this field after a measurement or layout operation
1798+
* has already taken place, a call to
1799+
* {@link ViewGroup#setLayoutParams(ViewGroup.LayoutParams)}
1800+
* must be made to notify GridLayout of the change. GridLayout is normally able
1801+
* to detect when code fails to observe this rule, issue a warning and take steps to
1802+
* compensate for the omission. This facility is implemented on a best effort basis
1803+
* and should not be relied upon in production code - so it is best to include the above
1804+
* calls to remove the warnings as soon as it is practical.
17701805
*/
17711806
public Spec rowSpec = Spec.UNDEFINED;
17721807

17731808
/**
17741809
* The spec that defines the horizontal characteristics of the cell group
17751810
* described by these layout parameters.
1811+
* If an assignment is made to this field after a measurement or layout operation
1812+
* has already taken place, a call to
1813+
* {@link ViewGroup#setLayoutParams(ViewGroup.LayoutParams)}
1814+
* must be made to notify GridLayout of the change. GridLayout is normally able
1815+
* to detect when code fails to observe this rule, issue a warning and take steps to
1816+
* compensate for the omission. This facility is implemented on a best effort basis
1817+
* and should not be relied upon in production code - so it is best to include the above
1818+
* calls to remove the warnings as soon as it is practical.
17761819
*/
17771820
public Spec columnSpec = Spec.UNDEFINED;
17781821

@@ -1917,6 +1960,26 @@ final void setRowSpecSpan(Interval span) {
19171960
final void setColumnSpecSpan(Interval span) {
19181961
columnSpec = columnSpec.copyWriteSpan(span);
19191962
}
1963+
1964+
@Override
1965+
public boolean equals(Object o) {
1966+
if (this == o) return true;
1967+
if (o == null || getClass() != o.getClass()) return false;
1968+
1969+
LayoutParams that = (LayoutParams) o;
1970+
1971+
if (!columnSpec.equals(that.columnSpec)) return false;
1972+
if (!rowSpec.equals(that.rowSpec)) return false;
1973+
1974+
return true;
1975+
}
1976+
1977+
@Override
1978+
public int hashCode() {
1979+
int result = rowSpec.hashCode();
1980+
result = 31 * result + columnSpec.hashCode();
1981+
return result;
1982+
}
19201983
}
19211984

19221985
/*

0 commit comments

Comments
 (0)