diff --git a/packages/core/platforms/android/widgets-release.aar b/packages/core/platforms/android/widgets-release.aar index f5eaa1a1b6..d27c48d18e 100644 Binary files a/packages/core/platforms/android/widgets-release.aar and b/packages/core/platforms/android/widgets-release.aar differ diff --git a/packages/core/ui/core/view/index.android.ts b/packages/core/ui/core/view/index.android.ts index 842a611293..2b2938a136 100644 --- a/packages/core/ui/core/view/index.android.ts +++ b/packages/core/ui/core/view/index.android.ts @@ -389,6 +389,15 @@ const INSET_TOP_CONSUMED = 20; const INSET_RIGHT_CONSUMED = 24; const INSET_BOTTOM_CONSUMED = 28; const INSET_BOTTOM_IME_CONSUMED = 36; +const INSET_CUTOUT_LEFT = 40; +const INSET_CUTOUT_TOP = 44; +const INSET_CUTOUT_RIGHT = 48; +const INSET_CUTOUT_BOTTOM = 52; + +const INSET_CUTOUT_LEFT_CONSUMED = 56; +const INSET_CUTOUT_TOP_CONSUMED = 60; +const INSET_CUTOUT_RIGHT_CONSUMED = 64; +const INSET_CUTOUT_BOTTOM_CONSUMED = 68; const OverflowEdgeIgnore = -1; const OverflowEdgeNone: number = 0; @@ -446,12 +455,12 @@ class Inset { this.view.setInt32(INSET_BOTTOM, value, true); } - public get ime(): number { + public get imeBottom(): number { return this.view.getInt32(INSET_BOTTOM_IME, true); } - public set ime(value: number) { - this.view.setInt32(INSET_BOTTOM, value, true); + public set imeBottom(value: number) { + this.view.setInt32(INSET_BOTTOM_IME, value, true); } public get leftConsumed(): boolean { @@ -494,8 +503,72 @@ class Inset { this.view.setInt32(INSET_BOTTOM_IME_CONSUMED, value ? 1 : 0, true); } + public get cutoutLeft(): number { + return this.view.getInt32(INSET_CUTOUT_LEFT, true); + } + + public set cutoutLeft(value: number) { + this.view.setInt32(INSET_CUTOUT_LEFT, value, true); + } + + public get cutoutTop(): number { + return this.view.getInt32(INSET_CUTOUT_TOP, true); + } + + public set cutoutTop(value: number) { + this.view.setInt32(INSET_CUTOUT_TOP, value, true); + } + + public get cutoutRight(): number { + return this.view.getInt32(INSET_CUTOUT_RIGHT, true); + } + + public set cutoutRight(value: number) { + this.view.setInt32(INSET_CUTOUT_RIGHT, value, true); + } + + public get cutoutBottom(): number { + return this.view.getInt32(INSET_CUTOUT_BOTTOM, true); + } + + public set cutoutBottom(value: number) { + this.view.setInt32(INSET_CUTOUT_BOTTOM, value, true); + } + + public get cutoutLeftConsumed(): boolean { + return this.view.getInt32(INSET_CUTOUT_LEFT_CONSUMED, true) > 0; + } + + public set cutoutLeftConsumed(value: boolean) { + this.view.setInt32(INSET_CUTOUT_LEFT_CONSUMED, value ? 1 : 0, true); + } + + public get cutoutTopConsumed(): boolean { + return this.view.getInt32(INSET_CUTOUT_TOP_CONSUMED, true) > 0; + } + + public set cutoutTopConsumed(value: boolean) { + this.view.setInt32(INSET_CUTOUT_TOP_CONSUMED, value ? 1 : 0, true); + } + + public get cutoutRightConsumed(): boolean { + return this.view.getInt32(INSET_CUTOUT_RIGHT_CONSUMED, true) > 0; + } + + public set cutoutRightConsumed(value: boolean) { + this.view.setInt32(INSET_CUTOUT_RIGHT_CONSUMED, value ? 1 : 0, true); + } + + public get cutoutBottomConsumed(): boolean { + return this.view.getInt32(INSET_CUTOUT_BOTTOM_CONSUMED, true) > 0; + } + + public set cutoutBottomConsumed(value: boolean) { + this.view.setInt32(INSET_CUTOUT_BOTTOM_CONSUMED, value ? 1 : 0, true); + } + toString() { - return `Inset: left=${this.left}, top=${this.top}, right=${this.right}, bottom=${this.bottom}, ` + `leftConsumed=${this.leftConsumed}, topConsumed=${this.topConsumed}, ` + `rightConsumed=${this.rightConsumed}, bottomConsumed=${this.bottomConsumed}`; + return `Inset: left=${this.left}, top=${this.top}, right=${this.right}, bottom=${this.bottom}, ` + `leftConsumed=${this.leftConsumed}, topConsumed=${this.topConsumed}, ` + `rightConsumed=${this.rightConsumed}, bottomConsumed=${this.bottomConsumed}, ` + `cutoutLeft=${this.cutoutLeft}, cutoutTop=${this.cutoutTop}, cutoutRight=${this.cutoutRight}, cutoutBottom=${this.cutoutBottom}, ` + `cutoutLeftConsumed=${this.cutoutLeftConsumed}, cutoutTopConsumed=${this.cutoutTopConsumed}, ` + `cutoutRightConsumed=${this.cutoutRightConsumed}, cutoutBottomConsumed=${this.cutoutBottomConsumed}`; } toJSON() { @@ -508,6 +581,14 @@ class Inset { topConsumed: this.topConsumed, rightConsumed: this.rightConsumed, bottomConsumed: this.bottomConsumed, + cutoutLeft: this.cutoutLeft, + cutoutTop: this.cutoutTop, + cutoutRight: this.cutoutRight, + cutoutBottom: this.cutoutBottom, + cutoutLeftConsumed: this.cutoutLeftConsumed, + cutoutTopConsumed: this.cutoutTopConsumed, + cutoutRightConsumed: this.cutoutRightConsumed, + cutoutBottomConsumed: this.cutoutBottomConsumed, }; } } diff --git a/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/LayoutBase.java b/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/LayoutBase.java index b22fc7f70b..8436de5f69 100644 --- a/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/LayoutBase.java +++ b/packages/ui-mobile-base/android/widgets/src/main/java/org/nativescript/widgets/LayoutBase.java @@ -59,11 +59,22 @@ public static final class BufferOffset { public static final int INSET_BOTTOM = 12; public static final int INSET_BOTTOM_IME = 32; + public static final int INSET_CUTOUT_LEFT = 40; + public static final int INSET_CUTOUT_TOP = 44; + public static final int INSET_CUTOUT_RIGHT = 48; + public static final int INSET_CUTOUT_BOTTOM = 52; + + public static final int INSET_LEFT_CONSUMED = 16; public static final int INSET_TOP_CONSUMED = 20; public static final int INSET_RIGHT_CONSUMED = 24; public static final int INSET_BOTTOM_CONSUMED = 28; public static final int INSET_BOTTOM_IME_CONSUMED = 36; + + public static final int INSET_CUTOUT_LEFT_CONSUMED = 56; + public static final int INSET_CUTOUT_TOP_CONSUMED = 60; + public static final int INSET_CUTOUT_RIGHT_CONSUMED = 64; + public static final int INSET_CUTOUT_BOTTOM_CONSUMED = 68; } int mPaddingLeft = 0; @@ -72,13 +83,21 @@ public static final class BufferOffset { int mPaddingBottom = 0; Insets edgeInsets = Insets.NONE; - Insets appliedInsets = Insets.NONE; Insets imeInsets = Insets.NONE; - int overflowEdge = OverflowEdgeIgnore; - private final ByteBuffer insetBuffer = ByteBuffer.allocateDirect(40); + private static final byte[] EMPTY_INSETS = new byte[72]; + + private ByteBuffer mInsetBuffer; + + private ByteBuffer getInsetBuffer() { + if (mInsetBuffer == null) { + mInsetBuffer = ByteBuffer.allocateDirect(72); + mInsetBuffer.order(ByteOrder.nativeOrder()); + } + return mInsetBuffer; + } private WindowInsetListener insetListener = null; private androidx.core.view.OnApplyWindowInsetsListener windowInsetsListener = null; @@ -91,8 +110,6 @@ public interface WindowInsetListener { void onApplyWindowInsets(ByteBuffer inset); } - private static final byte[] EMPTY_INSETS = new byte[40]; - private boolean pendingInsetApply = false; private final OnAttachStateChangeListener onAttachStateChangeListener = new OnAttachStateChangeListener() { @@ -112,7 +129,6 @@ public void onViewDetachedFromWindow(@NonNull View v) { public LayoutBase(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - insetBuffer.order(ByteOrder.nativeOrder()); } public LayoutBase(Context context) { @@ -222,16 +238,16 @@ public void setPadding(int left, int top, int right, int bottom) { } private void putInset(int offset, int value) { - insetBuffer.putInt(offset, value); + getInsetBuffer().putInt(offset, value); } private int getInset(int offset) { - return insetBuffer.getInt(offset); + return getInsetBuffer().getInt(offset); } private void resetInset() { - insetBuffer.position(0); - insetBuffer.put(EMPTY_INSETS, 0, 40); + getInsetBuffer().position(0); + getInsetBuffer().put(EMPTY_INSETS, 0, EMPTY_INSETS.length); } public void setOverflowEdge(int value) { @@ -254,6 +270,7 @@ public WindowInsetsCompat onApplyWindowInsets( Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); Insets ime = insets.getInsets(WindowInsetsCompat.Type.ime()); + Insets cutout = insets.getInsets(WindowInsetsCompat.Type.displayCutout()); if (systemBars == Insets.NONE && ime == Insets.NONE) { return WindowInsetsCompat.CONSUMED; @@ -357,14 +374,24 @@ public WindowInsetsCompat onApplyWindowInsets( putInset(BufferOffset.INSET_BOTTOM, insetNavBottom); putInset(BufferOffset.INSET_BOTTOM_IME, insetImeBottom); + putInset(BufferOffset.INSET_CUTOUT_LEFT, cutout.left); + putInset(BufferOffset.INSET_CUTOUT_TOP, cutout.top); + putInset(BufferOffset.INSET_CUTOUT_RIGHT, cutout.right); + putInset(BufferOffset.INSET_CUTOUT_BOTTOM, cutout.bottom); + putInset(BufferOffset.INSET_LEFT_CONSUMED, 0); putInset(BufferOffset.INSET_TOP_CONSUMED, 0); putInset(BufferOffset.INSET_RIGHT_CONSUMED, 0); putInset(BufferOffset.INSET_BOTTOM_CONSUMED, 0); putInset(BufferOffset.INSET_BOTTOM_IME_CONSUMED, 0); + putInset(BufferOffset.INSET_CUTOUT_LEFT_CONSUMED, 0); + putInset(BufferOffset.INSET_CUTOUT_TOP_CONSUMED, 0); + putInset(BufferOffset.INSET_CUTOUT_RIGHT_CONSUMED, 0); + putInset(BufferOffset.INSET_CUTOUT_BOTTOM_CONSUMED, 0); + if (base.insetListener != null) { - base.insetListener.onApplyWindowInsets(insetBuffer); + base.insetListener.onApplyWindowInsets(getInsetBuffer()); } defaultConsume[0] = defaultConsume[1] = defaultConsume[2] = defaultConsume[3] = false;