@@ -4,7 +4,7 @@ import type { GestureTypes, GestureEventData } from '../../gestures';
4
4
5
5
// Types.
6
6
import { ViewCommon , isEnabledProperty , originXProperty , originYProperty , isUserInteractionEnabledProperty } from './view-common' ;
7
- import { paddingLeftProperty , paddingTopProperty , paddingRightProperty , paddingBottomProperty } from '../../styling/style-properties' ;
7
+ import { paddingLeftProperty , paddingTopProperty , paddingRightProperty , paddingBottomProperty , Length } from '../../styling/style-properties' ;
8
8
import { layout } from '../../../utils' ;
9
9
import { Trace } from '../../../trace' ;
10
10
import { ShowModalOptions , hiddenProperty } from '../view-base' ;
@@ -14,6 +14,7 @@ import { perspectiveProperty, visibilityProperty, opacityProperty, horizontalAli
14
14
import { CoreTypes } from '../../../core-types' ;
15
15
16
16
import { Background , ad as androidBackground } from '../../styling/background' ;
17
+ import { BackgroundClearFlags , refreshBorderDrawable } from '../../styling/background.android' ;
17
18
import { profile } from '../../../profiling' ;
18
19
import { topmost } from '../../frame/frame-stack' ;
19
20
import { Screen } from '../../../platform' ;
@@ -23,6 +24,7 @@ import lazy from '../../../utils/lazy';
23
24
import { accessibilityEnabledProperty , accessibilityHiddenProperty , accessibilityHintProperty , accessibilityIdentifierProperty , accessibilityLabelProperty , accessibilityLanguageProperty , accessibilityLiveRegionProperty , accessibilityMediaSessionProperty , accessibilityRoleProperty , accessibilityStateProperty , accessibilityValueProperty } from '../../../accessibility/accessibility-properties' ;
24
25
import { AccessibilityLiveRegion , AccessibilityRole , AndroidAccessibilityEvent , setupAccessibleView , isAccessibilityServiceEnabled , sendAccessibilityEvent , updateAccessibilityProperties , updateContentDescription , AccessibilityState } from '../../../accessibility' ;
25
26
import * as Utils from '../../../utils' ;
27
+ import { CSSShadow } from '../../styling/css-shadow' ;
26
28
27
29
export * from './view-common' ;
28
30
// helpers (these are okay re-exported here)
@@ -56,6 +58,10 @@ const modalMap = new Map<number, DialogOptions>();
56
58
let TouchListener : TouchListener ;
57
59
let DialogFragment : DialogFragment ;
58
60
61
+ interface AndroidView {
62
+ _cachedDrawable : android . graphics . drawable . Drawable . ConstantState | android . graphics . drawable . Drawable ;
63
+ }
64
+
59
65
interface DialogOptions {
60
66
owner : View ;
61
67
fullscreen : boolean ;
@@ -1101,9 +1107,48 @@ export class View extends ViewCommon {
1101
1107
}
1102
1108
}
1103
1109
1110
+ public _applyBackground ( background : Background , isBorderDrawable : boolean , onlyColor : boolean , backgroundDrawable : any ) {
1111
+ const nativeView = this . nativeViewProtected ;
1112
+ if ( ! isBorderDrawable && onlyColor ) {
1113
+ if ( backgroundDrawable && backgroundDrawable . setColor ) {
1114
+ // android.graphics.drawable.ColorDrawable
1115
+ backgroundDrawable . setColor ( background . color . android ) ;
1116
+ backgroundDrawable . invalidateSelf ( ) ;
1117
+ } else {
1118
+ nativeView . setBackgroundColor ( background . color . android ) ;
1119
+ }
1120
+ } else if ( ! background . isEmpty ( ) ) {
1121
+ if ( isBorderDrawable ) {
1122
+ // org.nativescript.widgets.BorderDrawable
1123
+ refreshBorderDrawable ( this , backgroundDrawable ) ;
1124
+ } else {
1125
+ backgroundDrawable = new org . nativescript . widgets . BorderDrawable ( layout . getDisplayDensity ( ) , this . toString ( ) ) ;
1126
+ refreshBorderDrawable ( this , backgroundDrawable ) ;
1127
+ nativeView . setBackground ( backgroundDrawable ) ;
1128
+ }
1129
+ } else {
1130
+ //empty background let's reset
1131
+ const cachedDrawable = ( < any > nativeView ) . _cachedDrawable ;
1132
+ nativeView . setBackground ( cachedDrawable ) ;
1133
+ }
1134
+ }
1135
+
1136
+ protected _drawBoxShadow ( boxShadow : CSSShadow ) {
1137
+ const nativeView = this . nativeViewProtected ;
1138
+ const config = {
1139
+ shadowColor : boxShadow . color . android ,
1140
+ cornerRadius : Length . toDevicePixels ( this . borderRadius as CoreTypes . LengthType , 0.0 ) ,
1141
+ spreadRadius : Length . toDevicePixels ( boxShadow . spreadRadius , 0.0 ) ,
1142
+ blurRadius : Length . toDevicePixels ( boxShadow . blurRadius , 0.0 ) ,
1143
+ offsetX : Length . toDevicePixels ( boxShadow . offsetX , 0.0 ) ,
1144
+ offsetY : Length . toDevicePixels ( boxShadow . offsetY , 0.0 ) ,
1145
+ } ;
1146
+ org . nativescript . widgets . Utils . drawBoxShadow ( nativeView , JSON . stringify ( config ) ) ;
1147
+ }
1148
+
1104
1149
_redrawNativeBackground ( value : android . graphics . drawable . Drawable | Background ) : void {
1105
1150
if ( value instanceof Background ) {
1106
- androidBackground . onBackgroundOrBorderPropertyChanged ( this ) ;
1151
+ this . onBackgroundOrBorderPropertyChanged ( ) ;
1107
1152
} else {
1108
1153
const nativeView = this . nativeViewProtected ;
1109
1154
nativeView . setBackground ( value ) ;
@@ -1119,9 +1164,59 @@ export class View extends ViewCommon {
1119
1164
} else {
1120
1165
nativeView . setPadding ( paddingLeft , paddingTop , paddingRight , paddingBottom ) ;
1121
1166
}
1167
+ }
1168
+ }
1169
+
1170
+ protected onBackgroundOrBorderPropertyChanged ( ) {
1171
+ const nativeView = < android . view . View & { _cachedDrawable : android . graphics . drawable . Drawable . ConstantState | android . graphics . drawable . Drawable } > this . nativeViewProtected ;
1172
+ if ( ! nativeView ) {
1173
+ return ;
1174
+ }
1175
+
1176
+ const background = this . style . backgroundInternal ;
1177
+
1178
+ if ( background . clearFlags & BackgroundClearFlags . CLEAR_BOX_SHADOW || background . clearFlags & BackgroundClearFlags . CLEAR_BACKGROUND_COLOR ) {
1179
+ // clear background if we're clearing the box shadow
1180
+ // or the background has been removed
1181
+ nativeView . setBackground ( null ) ;
1182
+ }
1183
+
1184
+ const drawable = nativeView . getBackground ( ) ;
1185
+ const androidView = ( < any > this ) as AndroidView ;
1186
+ // use undefined as not set. getBackground will never return undefined only Drawable or null;
1187
+ if ( androidView . _cachedDrawable === undefined && drawable ) {
1188
+ const constantState = drawable . getConstantState ( ) ;
1189
+ androidView . _cachedDrawable = constantState || drawable ;
1190
+ }
1191
+ const isBorderDrawable = drawable instanceof org . nativescript . widgets . BorderDrawable ;
1192
+
1193
+ // prettier-ignore
1194
+ const onlyColor = ! background . hasBorderWidth ( )
1195
+ && ! background . hasBorderRadius ( )
1196
+ && ! background . hasBoxShadow ( )
1197
+ && ! background . clipPath
1198
+ && ! background . image
1199
+ && ! ! background . color ;
1122
1200
1123
- ( < any > nativeView ) . background = undefined ;
1201
+ this . _applyBackground ( background , isBorderDrawable , onlyColor , drawable ) ;
1202
+
1203
+ if ( background . hasBoxShadow ( ) ) {
1204
+ this . _drawBoxShadow ( background . getBoxShadow ( ) ) ;
1205
+ }
1206
+
1207
+ // TODO: Can we move BorderWidths as separate native setter?
1208
+ // This way we could skip setPadding if borderWidth is not changed.
1209
+ const leftPadding = Math . ceil ( this . effectiveBorderLeftWidth + this . effectivePaddingLeft ) ;
1210
+ const topPadding = Math . ceil ( this . effectiveBorderTopWidth + this . effectivePaddingTop ) ;
1211
+ const rightPadding = Math . ceil ( this . effectiveBorderRightWidth + this . effectivePaddingRight ) ;
1212
+ const bottomPadding = Math . ceil ( this . effectiveBorderBottomWidth + this . effectivePaddingBottom ) ;
1213
+ if ( this . _isPaddingRelative ) {
1214
+ nativeView . setPaddingRelative ( leftPadding , topPadding , rightPadding , bottomPadding ) ;
1215
+ } else {
1216
+ nativeView . setPadding ( leftPadding , topPadding , rightPadding , bottomPadding ) ;
1124
1217
}
1218
+ // reset clear flags
1219
+ background . clearFlags = BackgroundClearFlags . NONE ;
1125
1220
}
1126
1221
1127
1222
public accessibilityAnnouncement ( message = this . accessibilityLabel ) : void {
0 commit comments