diff --git a/api/current.txt b/api/current.txt index 2bc93eeda54b0..ea6f190ca44c3 100755 --- a/api/current.txt +++ b/api/current.txt @@ -54349,6 +54349,7 @@ package android.widget { method public int getSourceWidth(); method public int getWidth(); method public float getZoom(); + method public boolean isForcePositionWithinWindowSystemInsetsBounds(); method public void setZoom(float); method public void show(float, float); method public void show(float, float, float, float); @@ -54361,6 +54362,7 @@ package android.widget { method public android.widget.Magnifier.Builder setCornerRadius(float); method public android.widget.Magnifier.Builder setDefaultSourceToMagnifierOffset(int, int); method public android.widget.Magnifier.Builder setElevation(float); + method public android.widget.Magnifier.Builder setForcePositionWithinWindowSystemInsetsBounds(boolean); method public android.widget.Magnifier.Builder setSize(int, int); method public android.widget.Magnifier.Builder setZoom(float); } diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java index 9da2a4307a934..9f509b1f3d0b7 100644 --- a/core/java/android/widget/Magnifier.java +++ b/core/java/android/widget/Magnifier.java @@ -93,6 +93,8 @@ public final class Magnifier { private final int mDefaultHorizontalSourceToMagnifierOffset; // The vertical offset between the source and window coords when #show(float, float) is used. private final int mDefaultVerticalSourceToMagnifierOffset; + // Whether the magnifier will be clamped inside the main surface and not overlap system insets. + private final boolean mForcePositionWithinWindowSystemInsetsBounds; // The parent surface for the magnifier surface. private SurfaceInfo mParentSurface; // The surface where the content will be copied from. @@ -141,6 +143,8 @@ public final class Magnifier { params.mHorizontalDefaultSourceToMagnifierOffset; mDefaultVerticalSourceToMagnifierOffset = params.mVerticalDefaultSourceToMagnifierOffset; + mForcePositionWithinWindowSystemInsetsBounds = + params.mForcePositionWithinWindowSystemInsetsBounds; // The view's surface coordinates will not be updated until the magnifier is first shown. mViewCoordinatesInSurface = new int[2]; } @@ -378,6 +382,17 @@ public final class Magnifier { return mDefaultVerticalSourceToMagnifierOffset; } + /** + * Returns whether the magnifier position will be adjusted such that the magnifier will be + * fully within the bounds of the main application window, by also avoiding any overlap with + * system insets (such as the one corresponding to the status bar). + * @return whether the magnifier position will be adjusted + * @see Magnifier.Builder#setForcePositionWithinWindowSystemInsetsBounds(boolean) + */ + public boolean isForcePositionWithinWindowSystemInsetsBounds() { + return mForcePositionWithinWindowSystemInsetsBounds; + } + /** * Returns the top left coordinates of the magnifier, relative to the surface of the * main application window. They will be determined by the coordinates of the last @@ -567,6 +582,11 @@ public final class Magnifier { * @return the current window coordinates, after they are clamped inside the parent surface */ private Point getCurrentClampedWindowCoordinates() { + if (!mForcePositionWithinWindowSystemInsetsBounds) { + // No position adjustment should be done, so return the raw coordinates. + return new Point(mWindowCoords); + } + final Rect windowBounds; if (mParentSurface.mIsMainWindowSurface) { final Insets systemInsets = mView.getRootWindowInsets().getSystemWindowInsets(); @@ -891,6 +911,7 @@ public final class Magnifier { private @FloatRange(from = 0f) float mCornerRadius; private int mHorizontalDefaultSourceToMagnifierOffset; private int mVerticalDefaultSourceToMagnifierOffset; + private boolean mForcePositionWithinWindowSystemInsetsBounds; /** * Construct a new builder for {@link Magnifier} objects. @@ -915,6 +936,7 @@ public final class Magnifier { mVerticalDefaultSourceToMagnifierOffset = a.getDimensionPixelSize(R.styleable.Magnifier_magnifierVerticalOffset, 0); a.recycle(); + mForcePositionWithinWindowSystemInsetsBounds = true; } /** @@ -999,6 +1021,28 @@ public final class Magnifier { return this; } + /** + * Defines the behavior of the magnifier when it is requested to position outside the + * surface of the main application window. The default value is {@code true}, which means + * that the position will be adjusted such that the magnifier will be fully within the + * bounds of the main application window, by also avoiding any overlap with system insets + * (such as the one corresponding to the status bar). If you require a custom behavior, this + * flag should be set to {@code false}, meaning that the magnifier will be able to cross the + * main application surface boundaries (and also overlap the system insets). This should be + * handled with care, when passing coordinates to {@link #show(float, float)}; note that: + *