diff --git a/lib/java/com/google/android/material/carousel/MaskableFrameLayout.java b/lib/java/com/google/android/material/carousel/MaskableFrameLayout.java index 89f9bcf8a6f..6337b140629 100644 --- a/lib/java/com/google/android/material/carousel/MaskableFrameLayout.java +++ b/lib/java/com/google/android/material/carousel/MaskableFrameLayout.java @@ -54,6 +54,7 @@ public class MaskableFrameLayout extends FrameLayout implements Maskable, Shapea @Nullable private OnMaskChangedListener onMaskChangedListener; @NonNull private ShapeAppearanceModel shapeAppearanceModel; private final MaskableDelegate maskableDelegate = createMaskableDelegate(); + @Nullable private Boolean savedForceCompatClippingEnabled = null; public MaskableFrameLayout(@NonNull Context context) { this(context, null); @@ -86,6 +87,24 @@ protected void onSizeChanged(int w, int h, int oldw, int oldh) { onMaskChanged(); } + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + // Restore any saved force compat clipping setting. + if (savedForceCompatClippingEnabled != null) { + maskableDelegate.setForceCompatClippingEnabled(this, savedForceCompatClippingEnabled); + } + } + + @Override + protected void onDetachedFromWindow() { + // When detaching from the window, force canvas clipping to avoid any transitions from releasing + // the mask outline set by the MaskableDelegate's ViewOutlineProvider, if any. + savedForceCompatClippingEnabled = maskableDelegate.isForceCompatClippingEnabled(); + maskableDelegate.setForceCompatClippingEnabled(this, true); + super.onDetachedFromWindow(); + } + @Override public void setShapeAppearanceModel(@NonNull ShapeAppearanceModel shapeAppearanceModel) { this.shapeAppearanceModel = @@ -160,7 +179,6 @@ private void onMaskChanged() { } } - /** * Set whether this view should always use canvas clipping to clip to its masked shape. * @@ -222,6 +240,10 @@ private abstract static class MaskableDelegate { */ abstract boolean shouldUseCompatClipping(); + boolean isForceCompatClippingEnabled() { + return forceCompatClippingEnabled; + } + /** * Set whether the client would like to always use compat clipping regardless of whether other * means are available. @@ -366,8 +388,8 @@ public void getOutline(View view, Outline outline) { } /** - * A {@link MaskableDelegate} for API 33+ that uses {@link ViewOutlineProvider} to clip for - * all shapes. + * A {@link MaskableDelegate} for API 33+ that uses {@link ViewOutlineProvider} to clip for all + * shapes. * *

{@link Outline#setPath(Path)} was added in API 33 and allows using {@link * ViewOutlineProvider} to clip for all shapes.