2121import android .util .AttributeSet ;
2222import android .view .View ;
2323import android .view .ViewGroup ;
24- import androidx .annotation .NonNull ;
2524import androidx .annotation .Nullable ;
2625import androidx .annotation .Px ;
2726import com .google .android .material .animation .AnimationUtils ;
@@ -53,6 +52,8 @@ public class ListItemRevealLayout extends ViewGroup implements RevealableListIte
5352
5453 // TODO:b/443149411 - Make the min child width customizable
5554 private static final int MIN_CHILD_WIDTH = 15 ;
55+ private int originalWidthMeasureSpec = UNSET ;
56+ private int originalHeightMeasureSpec = UNSET ;
5657
5758 public ListItemRevealLayout (Context context ) {
5859 this (context , null );
@@ -70,7 +71,11 @@ public ListItemRevealLayout(Context context, AttributeSet attrs, int defStyleAtt
7071 @ Override
7172 protected void onMeasure (int widthMeasureSpec , int heightMeasureSpec ) {
7273 int childCount = getChildCount ();
73- if (intrinsicWidth == UNSET ) {
74+ if (shouldRemeasureIntrinsicSizes (originalHeightMeasureSpec , heightMeasureSpec , intrinsicHeight )
75+ || shouldRemeasureIntrinsicSizes (
76+ originalWidthMeasureSpec , widthMeasureSpec , intrinsicWidth )) {
77+ originalHeightMeasureSpec = heightMeasureSpec ;
78+ originalWidthMeasureSpec = widthMeasureSpec ;
7479 measureIntrinsicSize (widthMeasureSpec , heightMeasureSpec );
7580 // At this point all the children are measured and we have our intrinsic sizes, so we can
7681 // go through and save the original intrinsic child sizes
@@ -141,6 +146,26 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) {
141146 }
142147 }
143148
149+ private boolean shouldRemeasureIntrinsicSizes (
150+ int originalMeasureSpec , int newMeasureSpec , int intrinsicSize ) {
151+ // We only want to measure the intrinsic size if we don't know it yet, OR if the measure spec
152+ // has changed and it might be different than the existing intrinsic measured size. We assume
153+ // that if the MeasureSpec mode is UNSPECIFIED, we can use the existing intrinsic sizes. This
154+ // is to prevent unnecessary re-measuring when our parent continually gives us an unspecified
155+ // measure spec.
156+ if (intrinsicSize == UNSET ) {
157+ return true ;
158+ }
159+ if (originalMeasureSpec == newMeasureSpec ) {
160+ return false ;
161+ }
162+ int mode = MeasureSpec .getMode (newMeasureSpec );
163+ // We don't want to re-measure if the new measure spec is UNSPECIFIED, or if it's EXACTLY
164+ // the same as the intrinsic size.
165+ return mode != MeasureSpec .UNSPECIFIED
166+ && (mode != MeasureSpec .EXACTLY || MeasureSpec .getSize (newMeasureSpec ) != intrinsicSize );
167+ }
168+
144169 void measureIntrinsicSize (int widthMeasureSpec , int heightMeasureSpec ) {
145170 int totalWidth = 0 ;
146171 int maxHeight = 0 ;
@@ -300,15 +325,6 @@ protected LayoutParams generateLayoutParams(LayoutParams p) {
300325 return new MarginLayoutParams (p );
301326 }
302327
303- @ Override
304- public void setLayoutParams (@ NonNull LayoutParams params ) {
305- if (getLayoutParams () != null && params .width != getLayoutParams ().width ) {
306- // If not equal to previous layout params width, reset intrinsic width
307- resetIntrinsicWidth ();
308- }
309- super .setLayoutParams (params );
310- }
311-
312328 /**
313329 * Resets the intrinsic width remembered by the ListItemRevealLayout. This will cause a re-measure
314330 * of the ListItemRevealLayout and its children, and should only be called when a re-measure is
0 commit comments