• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:&nbsp;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![attributeModifier_ifelse](figures/attributeModifier_ifelse.gif)
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![attributeModifier_ifelse](figures/attributeModifier_ifelse.gif)
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![attributeModifier2](figures/attributeModifier2.gif)
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![attributeModifier](figures/attributeModifier.gif)
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