• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 多态样式
2<!--Kit: ArkUI-->
3<!--Subsystem: ArkUI-->
4<!--Owner: @jiangtao92-->
5<!--Designer: @piggyguy-->
6<!--Tester: @songyanhong-->
7<!--Adviser: @HelloCrease-->
8
9设置组件不同状态下的样式。
10
11>  **说明:**
12>
13>  从API version 8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
14>
15>  从API version 11开始支持另一种写法[attributeModifier](./ts-universal-attributes-attribute-modifier.md),可根据开发者需要动态设置属性。
16>
17>  多态样式仅支持[通用属性](ts-component-general-attributes.md)。如果多态样式不生效,则该属性可能为组件的私有属性,例如:[fontColor](./ts-universal-attributes-text-style.md)、[TextInput](./ts-basic-components-textinput.md)组件的[backgroundColor](./ts-universal-attributes-background.md#backgroundcolor18)等。此时,可以通过attributeModifier动态设置组件属性来解决此问题。
18>
19>  当前多态样式实现依赖于组件自定义节点的刷新机制。因Builder不具备独立的自定义父节点,无法直接触发刷新,致使多态样式无法直接在Builder中生效。解决方法是将多态样式封装至自定义组件内部,再将此组件置于@Builder中,以此来间接实现多态样式。示例代码可参考[示例3设置Builder多态样式](#示例3设置builder多态样式)。
20
21## stateStyles
22
23stateStyles(value: StateStyles): T
24
25设置组件不同状态的样式。
26
27**卡片能力:** 从API version 9开始,该接口支持在ArkTS卡片中使用。
28
29**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
30
31**系统能力:** SystemCapability.ArkUI.ArkUI.Full
32
33**参数:**
34
35| 参数名 | 类型                                | 必填 | 说明                     |
36| ------ | ----------------------------------- | ---- | ------------------------ |
37| value  | [StateStyles](#statestyles) | 是   | 设置组件不同状态的样式。 |
38
39**返回值:**
40
41| 类型 | 说明 |
42| -------- | -------- |
43| T | 返回当前组件。 |
44
45## StateStyles
46
47**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
48
49**系统能力:** SystemCapability.ArkUI.ArkUI.Full
50
51| 名称 | 类型 | 只读 | 可选 | 说明 |
52| -------- | -------- | -------- | -------- | -------- |
53| normal | any | 否 | 是 | 组件无状态时的样式。只支持传入@style修饰的样式代码块。<br/>**卡片能力:** 从API version 9开始,该接口支持在ArkTS卡片中使用。 |
54| pressed | any | 否 | 是 | 组件按下状态的样式。只支持传入@style修饰的样式代码块。<br/>**卡片能力:** 从API version 9开始,该接口支持在ArkTS卡片中使用。 |
55| disabled | any | 否 | 是 | 组件禁用状态的样式。只支持传入@style修饰的样式代码块。<br/>**卡片能力:** 从API version 9开始,该接口支持在ArkTS卡片中使用。 |
56| focused | any | 否 | 是 | 组件获焦状态的样式。只支持传入@style修饰的样式代码块。<br/>**卡片能力:** 从API version 9开始,该接口支持在ArkTS卡片中使用。 |
57| clicked | any | 否 | 是 | 组件点击状态的样式。只支持传入@style修饰的样式代码块。<br/>**卡片能力:** 从API version 9开始,该接口支持在ArkTS卡片中使用。 |
58| selected<sup>10+</sup> | object | 否 | 是 | 组件选中状态的样式。只支持传入@style修饰的样式代码块。<br/>**卡片能力:** 从API version 10开始,该接口支持在ArkTS卡片中使用。 |
59
60**selected选中状态说明**
61
62- 当前多态样式的选中状态样式依赖组件选中属性值,可以使用[onClick](ts-universal-events-click.md)修改属性值,或使用属性自带[$$](../../../ui/state-management/arkts-two-way-sync.md)双向绑定功能。
63
64- 当前支持selected的组件及其参数/属性值:
65
66  | 组件                                                         | 支持的参数/属性 | 起始API版本 |
67  | ------------------------------------------------------------ | --------------- | ----------- |
68  | [Checkbox](ts-basic-components-checkbox.md) | select          | 10          |
69  | [CheckboxGroup](ts-basic-components-checkboxgroup.md) | selectAll       | 10          |
70  | [Radio](ts-basic-components-radio.md)  | checked         | 10          |
71  | [Toggle](ts-basic-components-toggle.md) | isOn            | 10          |
72  | [ListItem](ts-container-listitem.md) | selected         | 10          |
73  | [GridItem](ts-container-griditem.md) | selected         | 10          |
74  | [MenuItem](ts-basic-components-menuitem.md) | selected         | 10          |
75
76**pressed和clicked状态说明**
77
78- 当clicked和pressed同时在一个组件上使用时,只有后注册的状态才能生效。
79
80## 示例
81
82### 示例1(设置Text多态样式)
83
84该示例展示了状态为pressed和disabled时Text组件的样式变化。
85
86```ts
87// xxx.ets
88@Entry
89@Component
90struct StyleExample {
91  @State isEnable: boolean = true
92
93  @Styles pressedStyles():void {
94    .backgroundColor("#ED6F21")
95    .borderRadius(10)
96    .borderStyle(BorderStyle.Dashed)
97    .borderWidth(2)
98    .borderColor("#33000000")
99    .width(120)
100    .height(30)
101    .opacity(1)
102  }
103
104  @Styles disabledStyles():void {
105    .backgroundColor("#E5E5E5")
106    .borderRadius(10)
107    .borderStyle(BorderStyle.Solid)
108    .borderWidth(2)
109    .borderColor("#2a4c1919")
110    .width(90)
111    .height(25)
112    .opacity(1)
113  }
114
115  @Styles normalStyles():void {
116    .backgroundColor("#0A59F7")
117    .borderRadius(10)
118    .borderStyle(BorderStyle.Solid)
119    .borderWidth(2)
120    .borderColor("#33000000")
121    .width(100)
122    .height(25)
123    .opacity(1)
124  }
125
126  build() {
127    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) {
128      Text("normal")
129        .fontSize(14)
130        .fontColor(Color.White)
131        .opacity(0.5)
132        .stateStyles({
133          normal: this.normalStyles,
134        })
135        .margin({ bottom: 20 })
136        .textAlign(TextAlign.Center)
137      Text("pressed")
138        .backgroundColor("#0A59F7")
139        .borderRadius(20)
140        .borderStyle(BorderStyle.Dotted)
141        .borderWidth(2)
142        .borderColor(Color.Red)
143        .width(100)
144        .height(25)
145        .opacity(1)
146        .fontSize(14)
147        .fontColor(Color.White)
148        .stateStyles({
149          pressed: this.pressedStyles,
150        })
151        .margin({ bottom: 20 })
152        .textAlign(TextAlign.Center)
153      Text(this.isEnable == true ? "effective" : "disabled")
154        .backgroundColor("#0A59F7")
155        .borderRadius(20)
156        .borderStyle(BorderStyle.Solid)
157        .borderWidth(2)
158        .borderColor(Color.Gray)
159        .width(100)
160        .height(25)
161        .opacity(1)
162        .fontSize(14)
163        .fontColor(Color.White)
164        .enabled(this.isEnable)
165        .stateStyles({
166          disabled: this.disabledStyles,
167        })
168        .textAlign(TextAlign.Center)
169      Text("control disabled")
170        .onClick(() => {
171          this.isEnable = !this.isEnable
172          console.info(`${this.isEnable}`)
173        })
174    }
175    .width(350).height(300)
176  }
177}
178```
179
180![zh-cn_image_0000001188742468](figures/zh-cn_image_0000001188742468.gif)
181
182### 示例2(设置Radio多态样式)
183
184该示例展示了状态为selected时Radio组件的样式变化。
185
186```ts
187// xxx.ets
188@Entry
189@Component
190struct Index {
191  @State value: boolean = false
192  @State value2: boolean = false
193
194  @Styles
195  normalStyles(): void{
196    .backgroundColor("#E5E5E1")
197  }
198
199  @Styles
200  selectStyles(): void{
201    .backgroundColor("#ED6F21")
202    .borderWidth(2)
203  }
204
205  build() {
206    Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
207      Column() {
208        Text('Radio1')
209          .fontSize(25)
210        Radio({ value: 'Radio1', group: 'radioGroup1' })
211          .checked(this.value)
212          .height(50)
213          .width(50)
214          .borderWidth(0)
215          .borderRadius(30)
216          .onClick(() => {
217            this.value = !this.value
218          })
219          .stateStyles({
220            normal: this.normalStyles,
221            selected: this.selectStyles,
222          })
223      }
224      .margin(30)
225
226      Column() {
227        Text('Radio2')
228          .fontSize(25)
229        Radio({ value: 'Radio2', group: 'radioGroup2' })
230          .checked($$this.value2)
231          .height(50)
232          .width(50)
233          .borderWidth(0)
234          .borderRadius(30)
235          .stateStyles({
236            normal: this.normalStyles,
237            selected: this.selectStyles,
238          })
239      }
240      .margin(30)
241    }.padding({ top: 30 })
242  }
243}
244```
245
246![selected](figures/selected.gif)
247
248### 示例3(设置Builder多态样式)
249
250该示例展示了状态为pressed时Builder组件的样式变化。
251
252```ts
253import { ComponentContent } from '@kit.ArkUI';
254import { BusinessError } from '@kit.BasicServicesKit';
255
256@Component
257struct Child {
258  build() {
259    Row()
260      .zIndex(10)
261      .width(100)
262      .height(200)
263      .stateStyles({
264        normal: {
265          .backgroundColor(Color.Blue)
266        },
267        pressed: {
268          .backgroundColor(Color.Black)
269        }
270      })
271  }
272}
273
274@Builder
275function
276buildText() {
277  Child()
278}
279
280@Entry
281@Component
282struct Index {
283  private contentNode: ComponentContent<Object> =
284    new ComponentContent(this.getUIContext(), wrapBuilder(buildText));
285
286  build() {
287    Button().onClick((event: ClickEvent) => {
288      this.getUIContext()
289        .getPromptAction()
290        .openCustomDialog(this.contentNode)
291        .then(() => {
292          console.info('OpenCustomDialog complete.')
293        })
294        .catch((error: BusinessError) => {
295          let message = (error as BusinessError).message;
296          let code = (error as BusinessError).code;
297          console.error(`OpenCustomDialog args error code is ${code}, message is ${message}`);
298        })
299    })
300  }
301}
302```
303
304![Builder](figures/stateStyles_builder.gif)