diff --git a/apps/automated/src/ui/view/view-tests.android.ts b/apps/automated/src/ui/view/view-tests.android.ts index 6c2ddd565a..a2441f170c 100644 --- a/apps/automated/src/ui/view/view-tests.android.ts +++ b/apps/automated/src/ui/view/view-tests.android.ts @@ -324,6 +324,66 @@ export function testSetAndRemoveBackgroundColor() { }); } +function getNativeBackgroundColor(v: View): number { + const drawable = (v.android).getBackground(); + if (drawable instanceof org.nativescript.widgets.BorderDrawable) { + return drawable.getBackgroundColor(); + } else if (drawable instanceof android.graphics.drawable.ColorDrawable) { + return drawable.getColor(); + } + + return drawable ? undefined : 0; +} + +export function testSetTransparentAndRemoveBackgroundColorWithBorderRadius() { + const lbl = new Label(); + lbl.text = 'segment'; + lbl.borderRadius = 8; + lbl.backgroundColor = new Color('red'); + helper.buildUIAndRunTest(lbl, function (views: Array) { + helper.waitUntilLayoutReady(lbl); + TKUnit.assertEqual(getNativeBackgroundColor(lbl), new Color('red').android, 'BackgroundColor not applied correctly!'); + + lbl.backgroundColor = new Color('transparent'); + TKUnit.assertEqual(getNativeBackgroundColor(lbl), 0, 'transparent BackgroundColor not applied!'); + + lbl.backgroundColor = new Color('red'); + TKUnit.assertEqual(getNativeBackgroundColor(lbl), new Color('red').android, 'BackgroundColor not applied correctly!'); + + lbl.backgroundColor = unsetValue; + TKUnit.assertEqual(getNativeBackgroundColor(lbl), 0, 'BackgroundColor not removed!'); + }); +} + +export function testToggleClassBackgroundColorFromCssVariableWithBorderRadius() { + const stack = new StackLayout(); + stack.className = 'segments'; + stack.css = ` + .segments { --tile-color: red; } + .segment { border-radius: 8; background-color: transparent; } + .segment-selected { background-color: var(--tile-color); } + .no-transparent-segment { border-radius: 8; } + `; + const lbl = new Label(); + lbl.text = 'segment'; + lbl.className = 'segment segment-selected'; + stack.addChild(lbl); + helper.buildUIAndRunTest(stack, function (views: Array) { + helper.waitUntilLayoutReady(lbl); + const red = new Color('red').android; + TKUnit.assertEqual(getNativeBackgroundColor(lbl), red, 'selected BackgroundColor not applied!'); + + lbl.className = 'segment'; + TKUnit.assertEqual(getNativeBackgroundColor(lbl), 0, 'BackgroundColor should be transparent after deselection!'); + + lbl.className = 'no-transparent-segment segment-selected'; + TKUnit.assertEqual(getNativeBackgroundColor(lbl), red, 'selected BackgroundColor not applied!'); + + lbl.className = 'no-transparent-segment'; + TKUnit.assertEqual(getNativeBackgroundColor(lbl), 0, 'BackgroundColor should be reset after deselection!'); + }); +} + export function testBackgroundImage() { const lbl = _createLabelWithBorder(); lbl.className = 'myClass'; diff --git a/packages/core/ui/core/view/index.android.ts b/packages/core/ui/core/view/index.android.ts index 0d4e0cc7d6..ce11d87bc4 100644 --- a/packages/core/ui/core/view/index.android.ts +++ b/packages/core/ui/core/view/index.android.ts @@ -1283,13 +1283,14 @@ export class View extends ViewCommon { const nativeView = this.nativeViewProtected as NativeScriptAndroidView; const canUseOutlineProvider = !background.hasBorderWidth() && !background.hasBoxShadows() && !background.clipPath && !background.image && SDK_VERSION >= 21 && (SDK_VERSION >= 33 || background.hasUniformBorderRadius()); if (onlyColor || canUseOutlineProvider) { - const backgroundColor = background.color?.android; if (isBorderDrawable) { // We need to duplicate the drawable or we lose the "default" cached drawable backgroundDrawable = nativeView._cachedDrawable != null ? AndroidHelper.getCopyOrDrawable(nativeView._cachedDrawable, nativeView.getResources()) : null; nativeView.setBackground(backgroundDrawable); } - if (backgroundColor) { + // do not test the native color for truthiness: `transparent` is 0 + if (background.color) { + const backgroundColor = background.color.android; if (this.needsNativeDrawableFill && backgroundDrawable) { backgroundDrawable.mutate(); @@ -1298,6 +1299,19 @@ export class View extends ViewCommon { } else { nativeView.setBackgroundColor(backgroundColor); } + } else if (!isBorderDrawable && background.clearFlags & BackgroundClearFlags.CLEAR_BACKGROUND_COLOR) { + // background color was removed: restore the default background + if (this.needsNativeDrawableFill && backgroundDrawable) { + backgroundDrawable.mutate(); + + AndroidHelper.clearDrawableColor(backgroundDrawable); + backgroundDrawable.invalidateSelf(); + } else { + const defaultDrawable = nativeView._cachedDrawable ?? null; + if (backgroundDrawable !== defaultDrawable) { + nativeView.setBackground(defaultDrawable); + } + } } // borderDrawable is slow // let s use outline provider when we can