文章目录一、多态样式概述1.1 核心接口 stateStyles1.2 StateStyles 状态类型说明关键补充说明二、实战示例详解示例1Text组件多态样式normal/pressed/disabled状态2.1.1 示例目标2.1.2 完整代码2.1.3 代码规范解析示例2Radio组件选中态selected多态样式2.2.1 示例目标2.2.2 完整代码2.2.3 代码规范解析示例3Builder 中多态样式的兼容实现2.3.1 示例目标2.3.2 完整代码2.3.3 代码规范解析三、多态样式使用避坑总结一、多态样式概述多态样式是ArkUI提供的核心能力用于一键设置组件不同交互状态下的样式无需开发者手动通过状态变量做三元表达式绑定大幅简化样式逻辑提升代码可读性与可维护性。基础支持从API version 8开始支持ArkTS卡片从API version 9开始支持元服务从API version 11开始支持替代方案API version 11新增attributeModifier可实现更灵活的动态属性设置系统能力SystemCapability.ArkUI.ArkUI.Full1.1 核心接口 stateStyles用于给组件绑定不同状态的样式配置接口定义如下stateStyles(value:StateStyles):T参数名类型必填说明valueStateStyles是组件不同状态对应的样式配置注意该接口不支持在attributeModifier中调用。1.2 StateStyles 状态类型说明StateStyles定义了组件支持的所有交互状态所有状态仅支持传入Styles装饰的样式代码块详细说明如下状态名可选性说明最低支持版本normal可选组件无任何特殊状态时的默认样式API 8pressed可选组件按下状态的样式API 8disabled可选组件禁用状态的样式API 8focused可选组件获焦状态的样式API 8clicked可选组件点击状态的样式API 8selected可选组件选中状态的样式API 10关键补充说明selected选中态规则该状态样式依赖组件自身的选中属性值可通过点击事件修改属性值或使用$$双向绑定功能更新官方明确支持selected状态的组件如下组件绑定的选中属性起始API版本Checkboxselect10CheckboxGroupselectAll10Radiochecked10ToggleisOn10ListItemselected10GridItemselected10MenuItemselected10pressed与clicked冲突规则当两个状态同时在一个组件上使用时只有后注册的状态才能生效。焦点态规则多态样式的焦点态只有在焦点激活态开启时才能生效。二、实战示例详解示例1Text组件多态样式normal/pressed/disabled状态2.1.1 示例目标演示Text组件在默认态、按下态、禁用态三种场景下的样式自动切换同时实现禁用状态的手动开关控制。2.1.2 完整代码// xxx.etsEntryComponentstruct StyleExample{StateisEnable:booleantrueStylespressedStyles():void{.backgroundColor(#ED6F21).borderRadius(10).borderStyle(BorderStyle.Dashed).borderWidth(2).borderColor(#33000000).width(120).height(30).opacity(1)}StylesdisabledStyles():void{.backgroundColor(#E5E5E5).borderRadius(10).borderStyle(BorderStyle.Solid).borderWidth(2).borderColor(#2a4c1919).width(90).height(25).opacity(1)}StylesnormalStyles():void{.backgroundColor(#0A59F7).borderRadius(10).borderStyle(BorderStyle.Solid).borderWidth(2).borderColor(#33000000).width(100).height(25).opacity(1)}build(){Flex({direction:FlexDirection.Column,alignItems:ItemAlign.Center}){Text(normal).fontSize(14).fontColor(Color.White).opacity(0.5)// stateStyles设置组件无状态时的样式.stateStyles({normal:this.normalStyles,}).margin({bottom:20}).textAlign(TextAlign.Center)Text(pressed).backgroundColor(#0A59F7).borderRadius(20).borderStyle(BorderStyle.Dotted).borderWidth(2).borderColor(Color.Red).width(100).height(25).opacity(1).fontSize(14).fontColor(Color.White)// stateStyles设置组件按下状态时的样式.stateStyles({pressed:this.pressedStyles,}).margin({bottom:20}).textAlign(TextAlign.Center)Text(this.isEnabletrue?effective:disabled).backgroundColor(#0A59F7).borderRadius(20).borderStyle(BorderStyle.Solid).borderWidth(2).borderColor(Color.Gray).width(100).height(25).opacity(1).fontSize(14).fontColor(Color.White).enabled(this.isEnable)// stateStyles设置组件禁用状态时的样式.stateStyles({disabled:this.disabledStyles,}).textAlign(TextAlign.Center)Text(control disabled).onClick((){this.isEnable!this.isEnableconsole.info(${this.isEnable})})}.width(350).height(300)}}运行效果如图2.1.3 代码规范解析样式封装通过Styles装饰器分别封装了normal、pressed、disabled三种状态的样式块完全符合官方“多态样式仅支持传入Styles修饰的样式代码块”的规范。状态绑定第一个Text组件仅绑定normal状态组件无交互时自动应用该样式第二个Text组件绑定pressed状态手指按下组件时自动切换样式松开后恢复默认第三个Text组件通过enabled(this.isEnable)绑定禁用状态状态为false时自动应用disabledStyles样式。状态控制通过底部Text的点击事件切换isEnable变量实现禁用状态的手动开关验证了多态样式对状态变化的实时响应。示例2Radio组件选中态selected多态样式2.2.1 示例目标演示Radio组件在未选中、选中两种状态下的样式自动切换实现同一分组内单选按钮的互斥选中效果适配API 10新增的selected状态规范。2.2.2 完整代码EntryComponentstruct Index{Statevalue:booleanfalseStatevalue2:booleanfalseStylesnormalStyles():void{.backgroundColor(#E5E5E1)}StylesselectStyles():void{.backgroundColor(#ED6F21).borderWidth(2)}build(){Flex({direction:FlexDirection.Row,justifyContent:FlexAlign.Center,alignItems:ItemAlign.Center}){Column(){Text(Radio1).fontSize(25)Radio({value:Radio1,group:radioGroup})// 统一 group 实现互斥.checked(this.value).height(50).width(50).borderWidth(0).borderRadius(30).onChange((isChecked:boolean){// 用 onChange 替代 onClick更符合 Radio 语义this.valueisChecked}).stateStyles({normal:this.normalStyles,selected:this.selectStyles,})}.margin(30)Column(){Text(Radio2).fontSize(25)Radio({value:Radio2,group:radioGroup})// 同一 group.checked(this.value2).height(50).width(50).borderWidth(0).borderRadius(30).onChange((isChecked:boolean){this.value2isChecked}).stateStyles({normal:this.normalStyles,selected:this.selectStyles,})}.margin(30)}.padding({top:30})}}运行效果如图2.2.3 代码规范解析selected状态合规性Radio组件是官方明确支持selected状态的组件绑定checked属性作为选中状态的判断依据完全符合API 10的selected状态使用规范。选中状态更新通过Radio组件原生的onChange事件获取最新选中状态更新State装饰的状态变量同时官方也支持通过$$this.value2双向绑定的方式更新两种方式均可触发selected样式的自动切换。单选互斥实现两个Radio组件设置了相同的group属性系统会自动处理同一分组内的单选互斥逻辑无需开发者手动处理排他逻辑。样式自动切换无需手动通过三元表达式绑定backgroundColor当checked属性为true时自动应用selectStyles选中样式为false时自动应用normalStyles默认样式。示例3Builder 中多态样式的兼容实现2.3.1 示例目标解决官方明确的“多态样式无法直接在Builder中生效”的问题通过自定义组件封装的方式实现在Builder装饰的函数、自定义弹窗中正常使用多态样式。2.3.2 完整代码import{ComponentContent}fromkit.ArkUI;import{BusinessError}fromkit.BasicServicesKit;Componentstruct Child{build(){Row().zIndex(10).width(200).height(200).stateStyles({normal:{.backgroundColor(Color.Blue)},pressed:{.backgroundColor(Color.Black)}})}}BuilderfunctionbuildText(){Child()}EntryComponentstruct Index{privatecontentNode:ComponentContentObjectnewComponentContent(this.getUIContext(),wrapBuilder(buildText));build(){Column(){Button().margin({top:200}).onClick((event:ClickEvent){this.getUIContext().getPromptAction().openCustomDialog(this.contentNode).then((){console.info(OpenCustomDialog complete.)}).catch((error:BusinessError){letmessage(errorasBusinessError).message;letcode(errorasBusinessError).code;console.error(OpenCustomDialog args error code is${code}, message is${message});})})}.width(100%).height(100%)}}运行效果如图当点击小圆形正方形显示点击正方形时颜色会加深2.3.3 代码规范解析核心问题解决官方明确说明“因Builder不具备独立的自定义父节点无法直接触发刷新致使多态样式无法直接在Builder中生效”本示例采用官方推荐的解决方案将多态样式封装至自定义组件内部再将此组件置于Builder中间接实现多态样式的生效。自定义组件封装Child自定义组件内部完成stateStyles的绑定包含normal和pressed两种状态拥有独立的自定义节点可正常触发样式刷新。Builder中引用在buildText函数中仅引用封装好的Child组件不直接写多态样式规避了原生不支持的问题。自定义弹窗适配通过ComponentContent和wrapBuilder将Builder函数包装为弹窗内容点击按钮打开弹窗后弹窗内的组件可正常响应按下状态的样式切换验证了该方案的兼容性。三、多态样式使用避坑属性支持限制多态样式仅支持通用属性若样式不生效大概率是该属性为组件私有属性如Text的fontColor、TextInput的backgroundColor等此时需通过attributeModifier动态设置属性解决。Builder使用限制禁止直接在Builder中使用stateStyles必须封装到自定义组件内部后再引用否则样式无法触发刷新。状态冲突限制pressed和clicked状态不可同时注册使用仅后注册的状态会生效。接口调用限制stateStyles接口不支持在attributeModifier中调用二者不可混用。焦点态生效限制focused焦点态样式仅在系统焦点激活态开启时才能生效。selected状态限制仅官方明确支持的组件可使用selected状态必须绑定组件对应的选中属性通过事件或双向绑定更新属性值才能触发样式切换。总结多态样式stateStyles是ArkUI开发中简化状态样式管理的核心能力它将组件交互状态与样式逻辑解耦无需开发者手动编写大量的样式绑定逻辑大幅降低了代码维护成本。本文基于官方最新规范完整覆盖了多态样式的基础定义、接口规范、全场景实战示例以及官方明确的使用限制与避坑方案所有代码均可直接在HarmonyOS项目中运行适配API 8的运行环境。如果这篇文章对你有帮助欢迎点赞、收藏、关注你的支持是持续创作的动力
HarmonyOS6 ArkTS 多态样式 stateStyles 全解析与实战示例
文章目录一、多态样式概述1.1 核心接口 stateStyles1.2 StateStyles 状态类型说明关键补充说明二、实战示例详解示例1Text组件多态样式normal/pressed/disabled状态2.1.1 示例目标2.1.2 完整代码2.1.3 代码规范解析示例2Radio组件选中态selected多态样式2.2.1 示例目标2.2.2 完整代码2.2.3 代码规范解析示例3Builder 中多态样式的兼容实现2.3.1 示例目标2.3.2 完整代码2.3.3 代码规范解析三、多态样式使用避坑总结一、多态样式概述多态样式是ArkUI提供的核心能力用于一键设置组件不同交互状态下的样式无需开发者手动通过状态变量做三元表达式绑定大幅简化样式逻辑提升代码可读性与可维护性。基础支持从API version 8开始支持ArkTS卡片从API version 9开始支持元服务从API version 11开始支持替代方案API version 11新增attributeModifier可实现更灵活的动态属性设置系统能力SystemCapability.ArkUI.ArkUI.Full1.1 核心接口 stateStyles用于给组件绑定不同状态的样式配置接口定义如下stateStyles(value:StateStyles):T参数名类型必填说明valueStateStyles是组件不同状态对应的样式配置注意该接口不支持在attributeModifier中调用。1.2 StateStyles 状态类型说明StateStyles定义了组件支持的所有交互状态所有状态仅支持传入Styles装饰的样式代码块详细说明如下状态名可选性说明最低支持版本normal可选组件无任何特殊状态时的默认样式API 8pressed可选组件按下状态的样式API 8disabled可选组件禁用状态的样式API 8focused可选组件获焦状态的样式API 8clicked可选组件点击状态的样式API 8selected可选组件选中状态的样式API 10关键补充说明selected选中态规则该状态样式依赖组件自身的选中属性值可通过点击事件修改属性值或使用$$双向绑定功能更新官方明确支持selected状态的组件如下组件绑定的选中属性起始API版本Checkboxselect10CheckboxGroupselectAll10Radiochecked10ToggleisOn10ListItemselected10GridItemselected10MenuItemselected10pressed与clicked冲突规则当两个状态同时在一个组件上使用时只有后注册的状态才能生效。焦点态规则多态样式的焦点态只有在焦点激活态开启时才能生效。二、实战示例详解示例1Text组件多态样式normal/pressed/disabled状态2.1.1 示例目标演示Text组件在默认态、按下态、禁用态三种场景下的样式自动切换同时实现禁用状态的手动开关控制。2.1.2 完整代码// xxx.etsEntryComponentstruct StyleExample{StateisEnable:booleantrueStylespressedStyles():void{.backgroundColor(#ED6F21).borderRadius(10).borderStyle(BorderStyle.Dashed).borderWidth(2).borderColor(#33000000).width(120).height(30).opacity(1)}StylesdisabledStyles():void{.backgroundColor(#E5E5E5).borderRadius(10).borderStyle(BorderStyle.Solid).borderWidth(2).borderColor(#2a4c1919).width(90).height(25).opacity(1)}StylesnormalStyles():void{.backgroundColor(#0A59F7).borderRadius(10).borderStyle(BorderStyle.Solid).borderWidth(2).borderColor(#33000000).width(100).height(25).opacity(1)}build(){Flex({direction:FlexDirection.Column,alignItems:ItemAlign.Center}){Text(normal).fontSize(14).fontColor(Color.White).opacity(0.5)// stateStyles设置组件无状态时的样式.stateStyles({normal:this.normalStyles,}).margin({bottom:20}).textAlign(TextAlign.Center)Text(pressed).backgroundColor(#0A59F7).borderRadius(20).borderStyle(BorderStyle.Dotted).borderWidth(2).borderColor(Color.Red).width(100).height(25).opacity(1).fontSize(14).fontColor(Color.White)// stateStyles设置组件按下状态时的样式.stateStyles({pressed:this.pressedStyles,}).margin({bottom:20}).textAlign(TextAlign.Center)Text(this.isEnabletrue?effective:disabled).backgroundColor(#0A59F7).borderRadius(20).borderStyle(BorderStyle.Solid).borderWidth(2).borderColor(Color.Gray).width(100).height(25).opacity(1).fontSize(14).fontColor(Color.White).enabled(this.isEnable)// stateStyles设置组件禁用状态时的样式.stateStyles({disabled:this.disabledStyles,}).textAlign(TextAlign.Center)Text(control disabled).onClick((){this.isEnable!this.isEnableconsole.info(${this.isEnable})})}.width(350).height(300)}}运行效果如图2.1.3 代码规范解析样式封装通过Styles装饰器分别封装了normal、pressed、disabled三种状态的样式块完全符合官方“多态样式仅支持传入Styles修饰的样式代码块”的规范。状态绑定第一个Text组件仅绑定normal状态组件无交互时自动应用该样式第二个Text组件绑定pressed状态手指按下组件时自动切换样式松开后恢复默认第三个Text组件通过enabled(this.isEnable)绑定禁用状态状态为false时自动应用disabledStyles样式。状态控制通过底部Text的点击事件切换isEnable变量实现禁用状态的手动开关验证了多态样式对状态变化的实时响应。示例2Radio组件选中态selected多态样式2.2.1 示例目标演示Radio组件在未选中、选中两种状态下的样式自动切换实现同一分组内单选按钮的互斥选中效果适配API 10新增的selected状态规范。2.2.2 完整代码EntryComponentstruct Index{Statevalue:booleanfalseStatevalue2:booleanfalseStylesnormalStyles():void{.backgroundColor(#E5E5E1)}StylesselectStyles():void{.backgroundColor(#ED6F21).borderWidth(2)}build(){Flex({direction:FlexDirection.Row,justifyContent:FlexAlign.Center,alignItems:ItemAlign.Center}){Column(){Text(Radio1).fontSize(25)Radio({value:Radio1,group:radioGroup})// 统一 group 实现互斥.checked(this.value).height(50).width(50).borderWidth(0).borderRadius(30).onChange((isChecked:boolean){// 用 onChange 替代 onClick更符合 Radio 语义this.valueisChecked}).stateStyles({normal:this.normalStyles,selected:this.selectStyles,})}.margin(30)Column(){Text(Radio2).fontSize(25)Radio({value:Radio2,group:radioGroup})// 同一 group.checked(this.value2).height(50).width(50).borderWidth(0).borderRadius(30).onChange((isChecked:boolean){this.value2isChecked}).stateStyles({normal:this.normalStyles,selected:this.selectStyles,})}.margin(30)}.padding({top:30})}}运行效果如图2.2.3 代码规范解析selected状态合规性Radio组件是官方明确支持selected状态的组件绑定checked属性作为选中状态的判断依据完全符合API 10的selected状态使用规范。选中状态更新通过Radio组件原生的onChange事件获取最新选中状态更新State装饰的状态变量同时官方也支持通过$$this.value2双向绑定的方式更新两种方式均可触发selected样式的自动切换。单选互斥实现两个Radio组件设置了相同的group属性系统会自动处理同一分组内的单选互斥逻辑无需开发者手动处理排他逻辑。样式自动切换无需手动通过三元表达式绑定backgroundColor当checked属性为true时自动应用selectStyles选中样式为false时自动应用normalStyles默认样式。示例3Builder 中多态样式的兼容实现2.3.1 示例目标解决官方明确的“多态样式无法直接在Builder中生效”的问题通过自定义组件封装的方式实现在Builder装饰的函数、自定义弹窗中正常使用多态样式。2.3.2 完整代码import{ComponentContent}fromkit.ArkUI;import{BusinessError}fromkit.BasicServicesKit;Componentstruct Child{build(){Row().zIndex(10).width(200).height(200).stateStyles({normal:{.backgroundColor(Color.Blue)},pressed:{.backgroundColor(Color.Black)}})}}BuilderfunctionbuildText(){Child()}EntryComponentstruct Index{privatecontentNode:ComponentContentObjectnewComponentContent(this.getUIContext(),wrapBuilder(buildText));build(){Column(){Button().margin({top:200}).onClick((event:ClickEvent){this.getUIContext().getPromptAction().openCustomDialog(this.contentNode).then((){console.info(OpenCustomDialog complete.)}).catch((error:BusinessError){letmessage(errorasBusinessError).message;letcode(errorasBusinessError).code;console.error(OpenCustomDialog args error code is${code}, message is${message});})})}.width(100%).height(100%)}}运行效果如图当点击小圆形正方形显示点击正方形时颜色会加深2.3.3 代码规范解析核心问题解决官方明确说明“因Builder不具备独立的自定义父节点无法直接触发刷新致使多态样式无法直接在Builder中生效”本示例采用官方推荐的解决方案将多态样式封装至自定义组件内部再将此组件置于Builder中间接实现多态样式的生效。自定义组件封装Child自定义组件内部完成stateStyles的绑定包含normal和pressed两种状态拥有独立的自定义节点可正常触发样式刷新。Builder中引用在buildText函数中仅引用封装好的Child组件不直接写多态样式规避了原生不支持的问题。自定义弹窗适配通过ComponentContent和wrapBuilder将Builder函数包装为弹窗内容点击按钮打开弹窗后弹窗内的组件可正常响应按下状态的样式切换验证了该方案的兼容性。三、多态样式使用避坑属性支持限制多态样式仅支持通用属性若样式不生效大概率是该属性为组件私有属性如Text的fontColor、TextInput的backgroundColor等此时需通过attributeModifier动态设置属性解决。Builder使用限制禁止直接在Builder中使用stateStyles必须封装到自定义组件内部后再引用否则样式无法触发刷新。状态冲突限制pressed和clicked状态不可同时注册使用仅后注册的状态会生效。接口调用限制stateStyles接口不支持在attributeModifier中调用二者不可混用。焦点态生效限制focused焦点态样式仅在系统焦点激活态开启时才能生效。selected状态限制仅官方明确支持的组件可使用selected状态必须绑定组件对应的选中属性通过事件或双向绑定更新属性值才能触发样式切换。总结多态样式stateStyles是ArkUI开发中简化状态样式管理的核心能力它将组件交互状态与样式逻辑解耦无需开发者手动编写大量的样式绑定逻辑大幅降低了代码维护成本。本文基于官方最新规范完整覆盖了多态样式的基础定义、接口规范、全场景实战示例以及官方明确的使用限制与避坑方案所有代码均可直接在HarmonyOS项目中运行适配API 8的运行环境。如果这篇文章对你有帮助欢迎点赞、收藏、关注你的支持是持续创作的动力