@@ -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