1# 动态属性设置 2 3动态设置组件的属性,支持开发者在属性设置时使用if/else语法,且根据需要使用多态样式设置属性。 4 5> **说明:** 6> 7> 从API Version 11开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 8> 9> 在attributeModifier中设置的属性尽量不要与其他方法设置的属性相同,避免在页面刷新时attributeModifier不生效。 10> 11> attributeModifier不支持自定义组件。 12 13## attributeModifier 14 15attributeModifier(modifier: AttributeModifier\<T>) 16 17动态设置组件的属性方法。 18 19**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 20 21**系统能力:** SystemCapability.ArkUI.ArkUI.Full 22 23**参数:** 24 25| 参数名 | 类型 | 必填 | 说明 | 26| -------- | --------------------- | ---- | ------------------------------------------------------------ | 27| modifier | [AttributeModifier\<T>](#attributemodifiert) | 是 | 在当前组件上,动态设置属性方法,支持使用if/else语法。<br/>modifier: 属性修改器,开发者需要自定义class实现AttributeModifier接口。 | 28 29## AttributeModifier\<T> 30 31开发者需要自定义class实现AttributeModifier接口。 32 33**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 34 35**系统能力:** SystemCapability.ArkUI.ArkUI.Full 36 37### applyNormalAttribute 38applyNormalAttribute(instance: T) : void 39 40组件普通状态时的样式。 41 42**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 43 44**系统能力:** SystemCapability.ArkUI.ArkUI.Full 45 46### applyPressedAttribute 47applyPressedAttribute(instance: T) : void 48 49组件按压状态的样式。 50 51**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 52 53**系统能力:** SystemCapability.ArkUI.ArkUI.Full 54 55### applyFocusedAttribute 56applyFocusedAttribute(instance: T) : void 57 58组件获焦状态的样式。 59 60**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 61 62**系统能力:** SystemCapability.ArkUI.ArkUI.Full 63 64### applyDisabledAttribute 65applyDisabledAttribute(instance: T) : void 66 67组件禁用状态的样式。 68 69**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 70 71**系统能力:** SystemCapability.ArkUI.ArkUI.Full 72 73### applySelectedAttribute 74applySelectedAttribute(instance: T) : void 75 76组件选中状态的样式。 77 78开发者可根据需要自定义实现这些方法,通过传入的参数识别组件类型,对instance设置属性,支持使用if/else语法进行动态设置。 79 80**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 81 82**系统能力:** SystemCapability.ArkUI.ArkUI.Full 83 84**参数**: 85 86| 参数 | 描述 | 87| -------------------- | ------------------------------------------------------------ | 88| instance |组件的属性类,用来标识进行属性设置的组件的类型,比如Button组件的ButtonAttribute,Text组件的TextAttribute等。| 89 90**instance参数支持范围:** 91 92AlphabetIndexerAttribute、BadgeAttribute、BlankAttribute、ButtonAttribute、CalendarPickerAttribute、CanvasAttribute、CheckboxAttribute、CheckboxGroupAttribute、CircleAttribute、ColumnAttribute、ColumnSplitAttribute、ShapeAttribute、CommonAttribute、CounterAttribute、DataPanelAttribute、DatePickerAttribute、DividerAttribute、EllipseAttribute、FlexAttribute、FlowItemAttribute、FormLinkAttribute、GaugeAttribute、GridAttribute、GridColAttribute、ColumnAttribute、GridItemAttribute、GridRowAttribute、HyperlinkAttribute、ImageAttribute、ImageAnimatorAttribute、ImageSpanAttribute、LineAttribute、ListAttribute、ListItemAttribute、ListItemGroupAttribute、LoadingProgressAttribute、MarqueeAttribute、MenuAttribute、MenuItemAttribute、MenuItemGroupAttribute、NavDestinationAttribute、NavigationAttribute、NavigatorAttribute、NavRouterAttribute、PanelAttribute、PathAttribute、PatternLockAttribute、PolygonAttribute、PolylineAttribute、ProgressAttribute、QRCodeAttribute、RadioAttribute、RatingAttribute、RectAttribute、RefreshAttribute、RelativeContainerAttribute、RichEditorAttribute、RichTextAttribute、RowAttribute、RowSplitAttribute、ScrollAttribute、ScrollBarAttribute、SearchAttribute、SelectAttribute、ShapeAttribute、SideBarContainerAttribute、SliderAttribute、SpanAttribute、StackAttribute、StepperAttribute、StepperItemAttribute、SwiperAttribute、SymbolGlyphAttribute、TabContentAttribute、TabsAttribute、TextAttribute、TextAreaAttribute、TextClockAttribute、TextInputAttribute、TextPickerAttribute、TextTimerAttribute、TimePickerAttribute、ToggleAttribute、VideoAttribute、WaterFlowAttribute、XComponentAttribute、ParticleAttribute<!--Del-->、EffectComponentAttribute、FormComponentAttribute、PluginComponentAttribute、RemoteWindowAttribute、UIExtensionComponentAttribute<!--DelEnd-->。 93 94**属性支持范围:** 95 961. 不支持入参或者返回值为[CustomBuilder](ts-types.md#custombuilder8)的属性。 972. 不支持入参为[modifier](../../../ui/arkts-user-defined-modifier.md)类型的属性,具体为以下属性方法:[attributeModifier](#attributemodifier),[drawModifier](./ts-universal-attributes-draw-modifier.md)和[gestureModifier](./ts-universal-attributes-gesture-modifier.md)。 983. 不支持[animation](./ts-animatorproperty.md)属性。 994. 不支持[gesture](../../../ui/arkts-gesture-events-binding.md)类型的属性。 1005. 不支持[stateStyles](./ts-universal-attributes-polymorphic-style.md)属性。 1016. 不支持已废弃属性。 102<!--Del--> 1037. 不支持系统组件属性。<!--DelEnd--> 104 105不支持或者未实现的属性在使用时会抛出"Method not implemented."、"is not callable"等异常信息。具体Modifier支持范围同基类属性接口的支持范围,详见表格[Attribute支持范围](#attribute支持范围)。 106 107## 自定义Modifier 108从API version 12开始,开发者可使用自定义Modifier构建组件并配置属性,通过此自定义的Modifier可调用所封装组件的属性和样式接口。 109 110**自定义Modifier支持范围:** 111 112CommonModifier、ColumnModifier、ColumnSplitModifier、RowModifier、RowSplitModifier、SideBarContainerModifier、BlankModifier、DividerModifier、GridColModifier、GridRowModifier、NavDestinationModifier、NavigatorModifier、StackModifier、NavigationModifier、NavRouterModifier、StepperItemModifier、TabsModifier、GridModifier、GridItemModifier、ListModifier、ListItemModifier、ListItemGroupModifier、ScrollModifier、SwiperModifier、WaterFlowModifier、ButtonModifier、CounterModifier、TextPickerModifier、TimePickerModifier、ToggleModifier、CalendarPickerModifier、CheckboxModifier、CheckboxGroupModifier、DatePickerModifier、RadioModifier、RatingModifier、SelectModifier、SliderModifier、PatternLockModifier、SpanModifier、RichEditorModifier、RefreshModifier、SearchModifier、TextAreaModifier、TextModifier、TextInputModifier、ImageSpanModifier、ImageAnimatorModifier、ImageModifier、VideoModifier、DataPanelModifier、GaugeModifier、LoadingProgressModifier、MarqueeModifier、ProgressModifier、QRCodeModifier、TextClockModifier、TextTimerModifier、LineModifier、PathModifier、PolygonModifier、PolylineModifier、RectModifier、ShapeModifier、AlphabetIndexerModifier、FormComponentModifier、HyperlinkModifier、MenuModifier、MenuItemModifier、PanelModifier、SymbolGlyphModifier、ParticleModifier。 113未暴露的组件Modifier可以使用CommonModifier。 114 115**注意事项** 1161. 设置自定义Modifier给一个组件,该组件对应属性生效。 1172. 自定义Modifier属性值变化,组件对应属性也会变化。自定义Modifier类型为基类,构造的对象为子类对象,使用时要通过as进行类型断言为子类。 1183. 一个自定义Modifier设置给两个组件,Modifier属性变化的时候对两个组件同时生效。 1194. 一个Modifier设置了属性A和属性B,再设置属性C和属性D,4个属性同时在组件上生效。 1205. 自定义Modifier不支持@State标注的状态数据的变化感知,见示例2。 1216. 多次通过attributeModifier设置属性时,生效的属性为所有属性的并集,相同属性按照设置顺序生效。 122 123## 示例 124### 示例1(组件绑定Modifier切换背景颜色) 125 126该示例通过Button绑定Modifier实现了点击切换背景颜色的效果。 127 128```ts 129// xxx.ets 130class MyButtonModifier implements AttributeModifier<ButtonAttribute> { 131 isDark: boolean = false 132 133 applyNormalAttribute(instance: ButtonAttribute): void { 134 if (this.isDark) { 135 instance.backgroundColor(Color.Black) 136 } else { 137 instance.backgroundColor(Color.Red) 138 } 139 } 140} 141 142@Entry 143@Component 144struct attributeDemo { 145 @State modifier: MyButtonModifier = new MyButtonModifier() 146 147 build() { 148 Row() { 149 Column() { 150 Button("Button") 151 .attributeModifier(this.modifier) 152 .onClick(() => { 153 this.modifier.isDark = !this.modifier.isDark 154 }) 155 } 156 .width('100%') 157 } 158 .height('100%') 159 } 160} 161``` 162 163 164### 示例2(组件绑定Modifier实现按压态效果) 165 166该示例通过Button绑定Modifier实现了按压态的效果。如果配合状态管理V2使用,详情见:[Modifier与makeObserved](../../../quick-start/arkts-v1-v2-migration.md#modifier)。 167 168```ts 169// xxx.ets 170class MyButtonModifier implements AttributeModifier<ButtonAttribute> { 171 applyNormalAttribute(instance: ButtonAttribute): void { 172 instance.backgroundColor(Color.Black) 173 } 174 175 applyPressedAttribute(instance: ButtonAttribute): void { 176 instance.backgroundColor(Color.Red) 177 } 178} 179 180@Entry 181@Component 182struct attributePressedDemo { 183 @State modifier: MyButtonModifier = new MyButtonModifier() 184 185 build() { 186 Row() { 187 Column() { 188 Button("Button") 189 .attributeModifier(this.modifier) 190 } 191 .width('100%') 192 } 193 .height('100%') 194 } 195} 196``` 197 198 199### 示例3(自定义Modifier不支持感知@State装饰的状态数据变化) 200 201该示例通过状态数据设置自定义Modifier的宽度,自定义Modifier不支持感知@State装饰的状态数据变化,点击按钮后宽度不发生改变。 202 203```ts 204import { CommonModifier } from "@kit.ArkUI" 205 206const TEST_TAG : string = "AttributeModifier"; 207class MyModifier extends CommonModifier { 208 applyNormalAttribute(instance: CommonAttribute): void { 209 super.applyNormalAttribute?.(instance); 210 } 211} 212 213@Component 214struct MyImage1 { 215 @Link modifier: CommonModifier 216 217 build() { 218 Image($r("app.media.startIcon")).attributeModifier(this.modifier as MyModifier) 219 } 220} 221 222@Entry 223@Component 224struct Index { 225 index: number = 0; 226 @State width1: number = 100; 227 @State height1: number = 100; 228 @State myModifier: CommonModifier = new MyModifier().width(this.width1).height(this.height1).margin(10) 229 230 build() { 231 Column() { 232 Button($r("app.string.EntryAbility_label")) 233 .margin(10) 234 .onClick(() => { 235 console.log(TEST_TAG, "onClick") 236 this.index++; 237 if (this.index % 2 === 1) { 238 this.width1 = 10; 239 console.log(TEST_TAG, "setGroup1") 240 } else { 241 this.width1 = 10; 242 console.log(TEST_TAG, "setGroup2") 243 } 244 }) 245 MyImage1({ modifier: this.myModifier }) 246 } 247 .width('100%') 248 } 249} 250``` 251 252 253### 示例4(Modifier和自定义Modifier的属性同时生效) 254 255该示例通过自定义Modifier设置了width和height,点击按钮时设置borderStyle和borderWidth,点击后4个属性同时生效。 256 257```ts 258import { CommonModifier } from "@kit.ArkUI" 259 260const TEST_TAG: string = "AttributeModifier"; 261 262class MyModifier extends CommonModifier { 263 applyNormalAttribute(instance: CommonAttribute): void { 264 super.applyNormalAttribute?.(instance); 265 } 266 267 public setGroup1(): void { 268 this.borderStyle(BorderStyle.Dotted) 269 this.borderWidth(8) 270 } 271 272 public setGroup2(): void { 273 this.borderStyle(BorderStyle.Dashed) 274 this.borderWidth(8) 275 } 276} 277 278@Component 279struct MyImage1 { 280 @Link modifier: CommonModifier 281 282 build() { 283 Image($r("app.media.startIcon")).attributeModifier(this.modifier as MyModifier) 284 } 285} 286 287@Entry 288@Component 289struct Index { 290 @State myModifier: CommonModifier = new MyModifier().width(100).height(100).margin(10) 291 index: number = 0; 292 293 build() { 294 Column() { 295 Button($r("app.string.EntryAbility_label")) 296 .margin(10) 297 .onClick(() => { 298 console.log(TEST_TAG, "onClick") 299 this.index++; 300 if (this.index % 2 === 1) { 301 (this.myModifier as MyModifier).setGroup1() 302 console.log(TEST_TAG, "setGroup1") 303 } else { 304 (this.myModifier as MyModifier).setGroup2() 305 console.log(TEST_TAG, "setGroup2") 306 } 307 }) 308 MyImage1({ modifier: this.myModifier }) 309 } 310 .width('100%') 311 } 312} 313``` 314 315 316## Attribute支持范围 317 318未在表格中列举的属性默认为支持。 319 320**表1** CommonAttribute属性接口支持例外范围 321| 属性 | 支持情况 | 告警信息 | 备注 | 322| ------------------------ | -------- | ----------------------- | ----------------------------------------- | 323| accessibilityChecked | 不支持 | is not callable | - | 324| accessibilitySelected | 不支持 | is not callable | - | 325| accessibilityTextHint | 不支持 | is not callable | - | 326| accessibilityVirtualNode | 不支持 | is not callable | 不支持入参为CustomBuilder。 | 327| animation | 不支持 | Method not implemented. | 不支持animation相关属性。 | 328| attributeModifier | 不支持 | - | attributeModifier不支持嵌套使用,不生效。 | 329| background | 不支持 | Method not implemented. | 不支持入参为CustomBuilder。 | 330| backgroundFilter | 不支持 | is not callable | - | 331| bindContentCover | 不支持 | Method not implemented. | 不支持入参为CustomBuilder。 | 332| bindContextMenu | 不支持 | Method not implemented. | 不支持入参为CustomBuilder。 | 333| bindMenu | 不支持 | Method not implemented. | 不支持入参为CustomBuilder。 | 334| bindPopup | 不支持 | Method not implemented. | 不支持入参为CustomBuilder。 | 335| bindSheet | 不支持 | Method not implemented. | 不支持入参为CustomBuilder。 | 336| chainWeight | 不支持 | is not callable | - | 337| compositingFilter | 不支持 | is not callable | - | 338| drawModifier | 不支持 | is not callable | 不支持modifier相关的属性。 | 339| foregroundFilter | 不支持 | is not callable | - | 340| freeze | 不支持 | is not callable | - | 341| gesture | 不支持 | Method not implemented. | 不支持gesture相关的属性。 | 342| gestureModifier | 不支持 | is not callable | 不支持modifier相关的属性。 | 343| onAccessibilityHover | 不支持 | is not callable | - | 344| onChildTouchTest | 不支持 | is not callable | - | 345| onKeyEventDispatch | 不支持 | is not callable | - | 346| onPreDrag | 不支持 | Method not implemented. | - | 347| onTouchIntercept | 不支持 | is not callable | - | 348| onVisibleAreaChange | 不支持 | Method not implemented. | - | 349| parallelGesture | 不支持 | Method not implemented. | 不支持gesture相关的属性。 | 350| priorityGesture | 不支持 | Method not implemented. | 不支持gesture相关的属性。 | 351| reuseId | 不支持 | Method not implemented. | - | 352| safeAreaPadding | 不支持 | is not callable | - | 353| stateStyles | 不支持 | Method not implemented. | 不支持stateStyles相关的属性。 | 354| useSizeType | 不支持 | Method not implemented. | 不支持已废弃属性。 | 355| visualEffect | 不支持 | is not callable | - | 356| accessibilityDescription | 部分支持 | - | 不支持入参为Resource。 | 357| accessibilityText | 部分支持 | - | 不支持入参为Resource。 | 358| dragPreview | 部分支持 | Method not implemented. | 仅支持入参为string。 | 359