From 1fc6dc7d0dca5344dbc9cda23b979f6d268aede5 Mon Sep 17 00:00:00 2001 From: Dimitris - Rafail Katsampas Date: Sat, 28 Jun 2025 20:02:49 +0300 Subject: [PATCH 1/2] fix(android): RootLayout shade cover unexpected delay --- .../core/ui/layouts/root-layout/index.android.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/core/ui/layouts/root-layout/index.android.ts b/packages/core/ui/layouts/root-layout/index.android.ts index 5aae6ae4d7..3fce2ce380 100644 --- a/packages/core/ui/layouts/root-layout/index.android.ts +++ b/packages/core/ui/layouts/root-layout/index.android.ts @@ -4,6 +4,7 @@ import { RootLayoutBase, defaultShadeCoverOptions } from './root-layout-common'; import { TransitionAnimation, ShadeCoverOptions } from '.'; import { parseLinearGradient } from '../../../css/parser'; import { LinearGradient } from '../../styling/linear-gradient'; +import { layout } from '../../../utils'; export * from './root-layout-common'; @@ -38,11 +39,20 @@ export class RootLayout extends RootLayoutBase { } protected _initShadeCover(view: View, shadeOptions: ShadeCoverOptions): void { - const initialState = { + const options = { ...defaultShadeCoverOptions.animation.enterFrom, ...shadeOptions?.animation?.enterFrom, }; - this._playAnimation(this._getAnimationSet(view, initialState)); + const nativeView: android.view.View = view?.nativeViewProtected; + + if (nativeView) { + nativeView.setAlpha(options.opacity); + org.nativescript.widgets.ViewHelper.setScaleX(nativeView, float(options.scaleX)); + org.nativescript.widgets.ViewHelper.setScaleY(nativeView, float(options.scaleY)); + org.nativescript.widgets.ViewHelper.setTranslateX(nativeView, layout.toDevicePixels(options.translateX)); + org.nativescript.widgets.ViewHelper.setTranslateY(nativeView, layout.toDevicePixels(options.translateY)); + org.nativescript.widgets.ViewHelper.setRotate(nativeView, float(options.rotate)); + } } protected _updateShadeCover(view: View, shadeOptions: ShadeCoverOptions): Promise { @@ -51,6 +61,7 @@ export class RootLayout extends RootLayoutBase { ...shadeOptions, }; const duration = options.animation?.enterFrom?.duration || defaultShadeCoverOptions.animation.enterFrom.duration; + return this._playAnimation( this._getAnimationSet( view, From ccad490fc0bb25cb59c1525da3ce3fe3f14dab09 Mon Sep 17 00:00:00 2001 From: Dimitris - Rafail Katsampas Date: Sat, 28 Jun 2025 21:02:41 +0300 Subject: [PATCH 2/2] fix: Avoid unsetting shade cover background during close --- .../ui/layouts/root-layout/index.android.ts | 49 +++++++++---------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/packages/core/ui/layouts/root-layout/index.android.ts b/packages/core/ui/layouts/root-layout/index.android.ts index 3fce2ce380..74e57b1f6d 100644 --- a/packages/core/ui/layouts/root-layout/index.android.ts +++ b/packages/core/ui/layouts/root-layout/index.android.ts @@ -47,11 +47,11 @@ export class RootLayout extends RootLayoutBase { if (nativeView) { nativeView.setAlpha(options.opacity); - org.nativescript.widgets.ViewHelper.setScaleX(nativeView, float(options.scaleX)); - org.nativescript.widgets.ViewHelper.setScaleY(nativeView, float(options.scaleY)); - org.nativescript.widgets.ViewHelper.setTranslateX(nativeView, layout.toDevicePixels(options.translateX)); - org.nativescript.widgets.ViewHelper.setTranslateY(nativeView, layout.toDevicePixels(options.translateY)); - org.nativescript.widgets.ViewHelper.setRotate(nativeView, float(options.rotate)); + nativeView.setScaleX(float(options.scaleX)); + nativeView.setScaleY(float(options.scaleY)); + nativeView.setTranslationX(layout.toDevicePixels(options.translateX)); + nativeView.setTranslationY(layout.toDevicePixels(options.translateY)); + nativeView.setRotation(float(options.rotate)); } } @@ -61,6 +61,19 @@ export class RootLayout extends RootLayoutBase { ...shadeOptions, }; const duration = options.animation?.enterFrom?.duration || defaultShadeCoverOptions.animation.enterFrom.duration; + const isBackgroundGradient = options.color && options.color.startsWith('linear-gradient'); + + if (isBackgroundGradient) { + if (view.backgroundColor) { + view.backgroundColor = undefined; + } + const parsedGradient = parseLinearGradient(options.color); + view.backgroundImage = LinearGradient.parse(parsedGradient.value); + } else { + if (view.backgroundImage) { + view.backgroundImage = undefined; + } + } return this._playAnimation( this._getAnimationSet( @@ -73,7 +86,7 @@ export class RootLayout extends RootLayoutBase { rotate: 0, opacity: options.opacity, }, - options.color, + isBackgroundGradient ? null : options.color, ), duration, ); @@ -88,30 +101,16 @@ export class RootLayout extends RootLayoutBase { } private _getAnimationSet(view: View, shadeCoverAnimation: TransitionAnimation, backgroundColor?: string): Array { - const isBackgroundGradient = backgroundColor && backgroundColor.startsWith('linear-gradient'); - - const animationSet = Array.create(android.animation.Animator, !backgroundColor || isBackgroundGradient ? 6 : 7); - animationSet[0] = android.animation.ObjectAnimator.ofFloat(view.nativeViewProtected, 'translationX', [shadeCoverAnimation.translateX]); - animationSet[1] = android.animation.ObjectAnimator.ofFloat(view.nativeViewProtected, 'translationY', [shadeCoverAnimation.translateY]); + const animationSet = Array.create(android.animation.Animator, backgroundColor ? 7 : 6); + animationSet[0] = android.animation.ObjectAnimator.ofFloat(view.nativeViewProtected, 'translationX', [layout.toDevicePixels(shadeCoverAnimation.translateX)]); + animationSet[1] = android.animation.ObjectAnimator.ofFloat(view.nativeViewProtected, 'translationY', [layout.toDevicePixels(shadeCoverAnimation.translateY)]); animationSet[2] = android.animation.ObjectAnimator.ofFloat(view.nativeViewProtected, 'scaleX', [shadeCoverAnimation.scaleX]); animationSet[3] = android.animation.ObjectAnimator.ofFloat(view.nativeViewProtected, 'scaleY', [shadeCoverAnimation.scaleY]); animationSet[4] = android.animation.ObjectAnimator.ofFloat(view.nativeViewProtected, 'rotation', [shadeCoverAnimation.rotate]); animationSet[5] = android.animation.ObjectAnimator.ofFloat(view.nativeViewProtected, 'alpha', [shadeCoverAnimation.opacity]); - if (isBackgroundGradient) { - if (view.backgroundColor) { - view.backgroundColor = undefined; - } - const parsedGradient = parseLinearGradient(backgroundColor); - view.backgroundImage = LinearGradient.parse(parsedGradient.value); - } else { - if (view.backgroundImage) { - view.backgroundImage = undefined; - } - - if (backgroundColor) { - animationSet[6] = this._getBackgroundColorAnimator(view, backgroundColor); - } + if (backgroundColor) { + animationSet[6] = this._getBackgroundColorAnimator(view, backgroundColor); } return animationSet; }