Skip to content

Commit 69e9676

Browse files
imhappipekingme
authored andcommitted
[Lists] Re-measure intrinsic width when measure specs change
PiperOrigin-RevId: 832002199
1 parent 692bd11 commit 69e9676

File tree

1 file changed

+27
-11
lines changed

1 file changed

+27
-11
lines changed

lib/java/com/google/android/material/listitem/ListItemRevealLayout.java

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import android.util.AttributeSet;
2222
import android.view.View;
2323
import android.view.ViewGroup;
24-
import androidx.annotation.NonNull;
2524
import androidx.annotation.Nullable;
2625
import androidx.annotation.Px;
2726
import 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

Comments
 (0)