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> **说明:** 38> 39> 在以下回调函数中,当对instance对象的同一个属性重复设置相同的值或对象时,不会触发该属性的更新。 40 41### applyNormalAttribute 42applyNormalAttribute(instance: T) : void 43 44组件普通状态时的样式。 45 46**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 47 48**系统能力:** SystemCapability.ArkUI.ArkUI.Full 49 50### applyPressedAttribute 51applyPressedAttribute(instance: T) : void 52 53组件按压状态的样式。 54 55**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 56 57**系统能力:** SystemCapability.ArkUI.ArkUI.Full 58 59### applyFocusedAttribute 60applyFocusedAttribute(instance: T) : void 61 62组件获焦状态的样式。 63 64**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 65 66**系统能力:** SystemCapability.ArkUI.ArkUI.Full 67 68### applyDisabledAttribute 69applyDisabledAttribute(instance: T) : void 70 71组件禁用状态的样式。 72 73**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 74 75**系统能力:** SystemCapability.ArkUI.ArkUI.Full 76 77### applySelectedAttribute 78applySelectedAttribute(instance: T) : void 79 80组件选中状态的样式。 81 82开发者可根据需要自定义实现这些方法,通过传入的参数识别组件类型,对instance设置属性,支持使用if/else语法进行动态设置。 83 84**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 85 86**系统能力:** SystemCapability.ArkUI.ArkUI.Full 87 88**参数**: 89 90| 参数 | 描述 | 91| -------- | ------------------------------------------------------------------------------------------------------------ | 92| instance | 组件的属性类,用来标识进行属性设置的组件的类型,比如Button组件的ButtonAttribute,Text组件的TextAttribute等。 | 93 94**instance参数支持范围:** 95 96AlphabetIndexerAttribute、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-->。 97 98**属性支持范围:** 99 1001. 不支持入参或者返回值为[CustomBuilder](ts-types.md#custombuilder8)的属性。 1012. 不支持入参为[modifier](../../../ui/arkts-user-defined-modifier.md)类型的属性,具体为以下属性方法:[attributeModifier](#attributemodifier),[drawModifier](./ts-universal-attributes-draw-modifier.md)和[gestureModifier](./ts-universal-attributes-gesture-modifier.md)。 1023. 不支持[animation](./ts-animatorproperty.md)属性。 1034. 不支持[gesture](../../../ui/arkts-gesture-events-binding.md)类型的属性。 1045. 不支持[stateStyles](./ts-universal-attributes-polymorphic-style.md)属性。 1056. 不支持已废弃属性。 106<!--Del--> 1077. 不支持系统组件属性。<!--DelEnd--> 108 109不支持或者未实现的属性在使用时会抛出"Method not implemented."、"is not callable"、"Builder is not supported."等异常信息。具体Modifier支持范围同基类属性接口的支持范围,详见表格[Attribute支持范围](#attribute支持范围)。 110 111## 自定义Modifier 112从API version 12开始,开发者可使用自定义Modifier构建组件并配置属性,通过此自定义的Modifier可调用所封装组件的属性和样式接口。 113 114**自定义Modifier支持范围:** 115 116CommonModifier、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。 117未暴露的组件Modifier可以使用CommonModifier。 118 119**注意事项** 1201. 设置自定义Modifier给一个组件,该组件对应属性生效。 1212. 自定义Modifier属性值变化,组件对应属性也会变化。自定义Modifier类型为基类,构造的对象为子类对象,使用时要通过as进行类型断言为子类。 1223. 一个自定义Modifier设置给两个组件,Modifier属性变化的时候对两个组件同时生效。 1234. 一个Modifier设置了属性A和属性B,再设置属性C和属性D,4个属性同时在组件上生效。 1245. 自定义Modifier不支持@State标注的状态数据的变化感知,见示例2。 1256. 多次通过attributeModifier设置属性时,生效的属性为所有属性的并集,相同属性按照设置顺序生效。 126 127## 示例 128### 示例1(组件绑定Modifier切换背景颜色) 129 130该示例通过Button绑定Modifier实现了点击切换背景颜色的效果。 131 132```ts 133// xxx.ets 134class MyButtonModifier implements AttributeModifier<ButtonAttribute> { 135 isDark: boolean = false 136 137 applyNormalAttribute(instance: ButtonAttribute): void { 138 if (this.isDark) { 139 instance.backgroundColor(Color.Black) 140 } else { 141 instance.backgroundColor(Color.Red) 142 } 143 } 144} 145 146@Entry 147@Component 148struct attributeDemo { 149 @State modifier: MyButtonModifier = new MyButtonModifier() 150 151 build() { 152 Row() { 153 Column() { 154 Button("Button") 155 .attributeModifier(this.modifier) 156 .onClick(() => { 157 this.modifier.isDark = !this.modifier.isDark 158 }) 159 } 160 .width('100%') 161 } 162 .height('100%') 163 } 164} 165``` 166 167 168### 示例2(组件绑定Modifier实现按压态效果) 169 170该示例通过Button绑定Modifier实现了按压态的效果。如果配合状态管理V2使用,详情见:[Modifier与makeObserved](../../../ui/state-management/arkts-v1-v2-migration.md#modifier)。 171 172```ts 173// xxx.ets 174class MyButtonModifier implements AttributeModifier<ButtonAttribute> { 175 applyNormalAttribute(instance: ButtonAttribute): void { 176 instance.backgroundColor(Color.Black) 177 } 178 179 applyPressedAttribute(instance: ButtonAttribute): void { 180 instance.backgroundColor(Color.Red) 181 } 182} 183 184@Entry 185@Component 186struct attributePressedDemo { 187 @State modifier: MyButtonModifier = new MyButtonModifier() 188 189 build() { 190 Row() { 191 Column() { 192 Button("Button") 193 .attributeModifier(this.modifier) 194 } 195 .width('100%') 196 } 197 .height('100%') 198 } 199} 200``` 201 202 203### 示例3(自定义Modifier不支持感知@State装饰的状态数据变化) 204 205该示例通过状态数据设置自定义Modifier的宽度,自定义Modifier不支持感知@State装饰的状态数据变化,点击按钮后宽度不发生改变。 206 207```ts 208import { CommonModifier } from "@kit.ArkUI" 209 210const TEST_TAG : string = "AttributeModifier"; 211class MyModifier extends CommonModifier { 212 applyNormalAttribute(instance: CommonAttribute): void { 213 super.applyNormalAttribute?.(instance); 214 } 215} 216 217@Component 218struct MyImage1 { 219 @Link modifier: CommonModifier 220 221 build() { 222 Image($r("app.media.startIcon")).attributeModifier(this.modifier as MyModifier) 223 } 224} 225 226@Entry 227@Component 228struct Index { 229 index: number = 0; 230 @State width1: number = 100; 231 @State height1: number = 100; 232 @State myModifier: CommonModifier = new MyModifier().width(this.width1).height(this.height1).margin(10) 233 234 build() { 235 Column() { 236 Button($r("app.string.EntryAbility_label")) 237 .margin(10) 238 .onClick(() => { 239 console.log(TEST_TAG, "onClick") 240 this.index++; 241 if (this.index % 2 === 1) { 242 this.width1 = 10; 243 console.log(TEST_TAG, "setGroup1") 244 } else { 245 this.width1 = 10; 246 console.log(TEST_TAG, "setGroup2") 247 } 248 }) 249 MyImage1({ modifier: this.myModifier }) 250 } 251 .width('100%') 252 } 253} 254``` 255 256 257### 示例4(Modifier和自定义Modifier的属性同时生效) 258 259该示例通过自定义Modifier设置了width和height,点击按钮时设置borderStyle和borderWidth,点击后4个属性同时生效。 260 261```ts 262import { CommonModifier } from "@kit.ArkUI" 263 264const TEST_TAG: string = "AttributeModifier"; 265 266class MyModifier extends CommonModifier { 267 applyNormalAttribute(instance: CommonAttribute): void { 268 super.applyNormalAttribute?.(instance); 269 } 270 271 public setGroup1(): void { 272 this.borderStyle(BorderStyle.Dotted) 273 this.borderWidth(8) 274 } 275 276 public setGroup2(): void { 277 this.borderStyle(BorderStyle.Dashed) 278 this.borderWidth(8) 279 } 280} 281 282@Component 283struct MyImage1 { 284 @Link modifier: CommonModifier 285 286 build() { 287 Image($r("app.media.startIcon")).attributeModifier(this.modifier as MyModifier) 288 } 289} 290 291@Entry 292@Component 293struct Index { 294 @State myModifier: CommonModifier = new MyModifier().width(100).height(100).margin(10) 295 index: number = 0; 296 297 build() { 298 Column() { 299 Button($r("app.string.EntryAbility_label")) 300 .margin(10) 301 .onClick(() => { 302 console.log(TEST_TAG, "onClick") 303 this.index++; 304 if (this.index % 2 === 1) { 305 (this.myModifier as MyModifier).setGroup1() 306 console.log(TEST_TAG, "setGroup1") 307 } else { 308 (this.myModifier as MyModifier).setGroup2() 309 console.log(TEST_TAG, "setGroup2") 310 } 311 }) 312 MyImage1({ modifier: this.myModifier }) 313 } 314 .width('100%') 315 } 316} 317``` 318 319 320### 示例5(组件绑定Modifier获焦样式) 321 322该示例通过 Button 绑定 Modifier 实现了组件在获得焦点时的样式效果。点击 Button2 后,Button 会显示获得焦点后的样式。 323 324```ts 325class MyButtonModifier implements AttributeModifier<ButtonAttribute> { 326 327 applyNormalAttribute(instance: ButtonAttribute): void { 328 instance.backgroundColor(Color.Blue) 329 } 330 applyFocusedAttribute(instance: ButtonAttribute): void { 331 instance.backgroundColor(Color.Green) 332 } 333} 334 335@Entry 336@Component 337struct attributeDemo { 338 @State modifier: MyButtonModifier = new MyButtonModifier() 339 @State isDisable: boolean = true; 340 341 build() { 342 Row() { 343 Column() { 344 Button("Button") 345 .attributeModifier(this.modifier) 346 .enabled(this.isDisable) 347 .id("app") 348 Divider().vertical(false).strokeWidth(15).color(Color.Transparent) 349 Button("Button2") 350 .onClick(() => { 351 this.getUIContext().getFocusController().activate(true) 352 this.getUIContext().getFocusController().requestFocus("app") 353 }) 354 } 355 .width('100%') 356 } 357 .height('100%') 358 } 359} 360``` 361 362 363### 示例6(组件绑定Modifier禁用状态的样式) 364 365该示例通过 Button 绑定 Modifier 实现了组件禁用时的样式效果。点击 Button2 后,Button 会显示禁用状态的样式。 366 367```ts 368class MyButtonModifier implements AttributeModifier<ButtonAttribute> { 369 applyDisabledAttribute(instance: ButtonAttribute): void { 370 instance.width(200) 371 } 372} 373 374@Entry 375@Component 376struct attributeDemo { 377 @State modifier: MyButtonModifier = new MyButtonModifier() 378 @State isDisable: boolean = true 379 380 build() { 381 Row() { 382 Column() { 383 Button("Button") 384 .attributeModifier(this.modifier) 385 .enabled(this.isDisable) 386 Divider().vertical(false).strokeWidth(15).color(Color.Transparent) 387 Button("Button2") 388 .onClick(() => { 389 this.isDisable = !this.isDisable 390 }) 391 } 392 .width('100%') 393 } 394 .height('100%') 395 } 396} 397``` 398 399 400### 示例7(组件绑定Modifier选中状态样式) 401 402该示例通过Radio绑定Modifier实现了展示组件选中时样式的效果。 403 404```ts 405class MyRadioModifier implements AttributeModifier<RadioAttribute> { 406 applyNormalAttribute(instance: RadioAttribute): void { 407 instance.backgroundColor(Color.Blue) 408 } 409 applySelectedAttribute(instance: RadioAttribute): void { 410 instance.backgroundColor(Color.Red) 411 instance.borderWidth(2) 412 } 413} 414 415@Entry 416@Component 417struct attributeDemo { 418 @State modifier: MyRadioModifier = new MyRadioModifier() 419 @State value: boolean = false 420 @State value2: boolean = false 421 422 build() { 423 Row() { 424 Column() { 425 Radio({ value: 'Radio1', group: 'radioGroup1' }) 426 .checked(this.value) 427 .height(50) 428 .width(50) 429 .borderWidth(0) 430 .borderRadius(30) 431 .onClick(() => { 432 this.value = !this.value 433 }) 434 .attributeModifier(this.modifier) 435 } 436 .width('100%') 437 } 438 .height('100%') 439 } 440} 441``` 442 443 444## Attribute支持范围 445 446未在表格中列举的属性默认为支持。 447 448**表1** CommonAttribute属性接口支持例外范围 449 450| 属性 | 支持情况 | 告警信息 | 备注 | 451| ------------------------ | -------- | ------------------------- | ----------------------------------------- | 452| accessibilityChecked | 不支持 | is not callable | - | 453| accessibilitySelected | 不支持 | is not callable | - | 454| accessibilityTextHint | 不支持 | is not callable | - | 455| accessibilityVirtualNode | 不支持 | is not callable | 不支持入参为CustomBuilder。 | 456| animation | 不支持 | Method not implemented. | 不支持animation相关属性。 | 457| attributeModifier | 不支持 | - | attributeModifier不支持嵌套使用,不生效。 | 458| background | 不支持 | Method not implemented. | 不支持入参为CustomBuilder。 | 459| backgroundFilter | 不支持 | is not callable | - | 460| bindContentCover | 不支持 | Method not implemented. | 不支持入参为CustomBuilder。 | 461| bindContextMenu | 不支持 | Method not implemented. | 不支持入参为CustomBuilder。 | 462| bindPopup | 不支持 | Method not implemented. | 不支持入参为CustomBuilder。 | 463| bindSheet | 不支持 | Method not implemented. | 不支持入参为CustomBuilder。 | 464| chainWeight | 不支持 | is not callable | - | 465| compositingFilter | 不支持 | is not callable | - | 466| drawModifier | 不支持 | is not callable | 不支持modifier相关的属性。 | 467| foregroundFilter | 不支持 | is not callable | - | 468| freeze | 不支持 | is not callable | - | 469| gesture | 不支持 | Method not implemented. | 不支持gesture相关的属性。 | 470| gestureModifier | 不支持 | is not callable | 不支持modifier相关的属性。 | 471| onAccessibilityHover | 不支持 | is not callable | - | 472| onChildTouchTest | 不支持 | is not callable | - | 473| onDragStart | 不支持 | Method not implemented. | 不支持返回值为CustomBuilder。 | 474| onPreDrag | 不支持 | Method not implemented. | - | 475| onTouchIntercept | 不支持 | is not callable | - | 476| onVisibleAreaChange | 不支持 | Method not implemented. | - | 477| parallelGesture | 不支持 | Method not implemented. | 不支持gesture相关的属性。 | 478| priorityGesture | 不支持 | Method not implemented. | 不支持gesture相关的属性。 | 479| reuseId | 不支持 | Method not implemented. | - | 480| stateStyles | 不支持 | Method not implemented. | 不支持stateStyles相关的属性。 | 481| useSizeType | 不支持 | Method not implemented. | 不支持已废弃属性。 | 482| visualEffect | 不支持 | is not callable | - | 483| bindMenu | 部分支持 | - | 不支持入参为CustomBuilder。 | 484| dragPreview | 部分支持 | Builder is not supported. | 不支持入参为CustomBuilder。 | 485