summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/View.java30
-rw-r--r--core/tests/coretests/src/android/view/ViewGroupTest.java42
2 files changed, 66 insertions, 6 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 049189f8af8d..0681745a0fc6 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -28277,14 +28277,28 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mPrivateFlags |= PFLAG_FORCE_LAYOUT;
mPrivateFlags |= PFLAG_INVALIDATED;
- if (mParent != null && !mParent.isLayoutRequested()) {
- mParent.requestLayout();
+ if (mParent != null) {
+ if (!mParent.isLayoutRequested()) {
+ mParent.requestLayout();
+ } else {
+ clearMeasureCacheOfAncestors();
+ }
}
if (mAttachInfo != null && mAttachInfo.mViewRequestingLayout == this) {
mAttachInfo.mViewRequestingLayout = null;
}
}
+ private void clearMeasureCacheOfAncestors() {
+ ViewParent parent = mParent;
+ while (parent instanceof View view) {
+ if (view.mMeasureCache != null) {
+ view.mMeasureCache.clear();
+ }
+ parent = view.mParent;
+ }
+ }
+
/**
* Forces this view to be laid out during the next layout pass.
* This method does not call requestLayout() or forceLayout()
@@ -28640,8 +28654,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
@RemotableViewMethod
public void setMinimumHeight(int minHeight) {
- mMinHeight = minHeight;
- requestLayout();
+ if (mMinHeight != minHeight) {
+ mMinHeight = minHeight;
+ requestLayout();
+ }
}
/**
@@ -28671,8 +28687,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
@RemotableViewMethod
public void setMinimumWidth(int minWidth) {
- mMinWidth = minWidth;
- requestLayout();
+ if (mMinWidth != minWidth) {
+ mMinWidth = minWidth;
+ requestLayout();
+ }
}
diff --git a/core/tests/coretests/src/android/view/ViewGroupTest.java b/core/tests/coretests/src/android/view/ViewGroupTest.java
index ae3ad36b532c..43c404e849fe 100644
--- a/core/tests/coretests/src/android/view/ViewGroupTest.java
+++ b/core/tests/coretests/src/android/view/ViewGroupTest.java
@@ -213,6 +213,35 @@ public class ViewGroupTest {
assertTrue(autofillableViews.containsAll(Arrays.asList(viewA, viewC)));
}
+ @Test
+ public void testMeasureCache() {
+ final int spec1 = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.AT_MOST);
+ final int spec2 = View.MeasureSpec.makeMeasureSpec(50, View.MeasureSpec.AT_MOST);
+ final Context context = getInstrumentation().getContext();
+ final View child = new View(context);
+ final TestView parent = new TestView(context, 0);
+ parent.addView(child);
+
+ child.setPadding(1, 2, 3, 4);
+ parent.measure(spec1, spec1);
+ assertEquals(4, parent.getMeasuredWidth());
+ assertEquals(6, parent.getMeasuredHeight());
+
+ child.setPadding(5, 6, 7, 8);
+ parent.measure(spec2, spec2);
+ assertEquals(12, parent.getMeasuredWidth());
+ assertEquals(14, parent.getMeasuredHeight());
+
+ // This ends the state of forceLayout.
+ parent.layout(0, 0, 50, 50);
+
+ // The cached values should be cleared after the new setPadding is called. And the measured
+ // width and height should be up-to-date.
+ parent.measure(spec1, spec1);
+ assertEquals(12, parent.getMeasuredWidth());
+ assertEquals(14, parent.getMeasuredHeight());
+ }
+
private static void getUnobscuredTouchableRegion(Region outRegion, View view) {
outRegion.set(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
final ViewParent parent = view.getParent();
@@ -240,6 +269,19 @@ public class ViewGroupTest {
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// We don't layout this view.
}
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int measuredWidth = 0;
+ int measuredHeight = 0;
+ final int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ measuredWidth += child.getPaddingLeft() + child.getPaddingRight();
+ measuredHeight += child.getPaddingTop() + child.getPaddingBottom();
+ }
+ setMeasuredDimension(measuredWidth, measuredHeight);
+ }
}
public static class AutofillableTestView extends TestView {