diff options
| -rw-r--r-- | core/java/android/view/View.java | 30 | ||||
| -rw-r--r-- | core/tests/coretests/src/android/view/ViewGroupTest.java | 42 |
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 { |