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 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 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