鸿蒙开发 - 支持导出,跨文件使用的自定义样式 AttributeModifier

news/2025/2/11 10:01:41/文章来源:https://www.cnblogs.com/naturl/p/18709164

我们在自定义组件的时候,无论是用 @Styles 还是 @Extend,都很难真正做到独立的封装样式,因为这两者都不支持导出,不可以跨文件调用

这篇文章主要介绍一个接口 AttributeModifier,它很好的解决了这些弊端,可以实现样式的集中管理和复用,支持跨文件调用封装好的样式类

AttributeModifier

使用介绍

AttributeModifier 是一个接口,我们需要实现其中的一个方法 apply<状态名称>Attribute,来实现不同的场景

状态名称分为:默认态(Normal)、按压态(Pressed)、焦点态(Focused)、禁用态(Disabled)、选择态(Selected)

如果想设置元素的默认样式,就是 applyNormalAttribute,如果想设置元素的按压场景下的样式,就是 applyPressedAttribute

declare interface AttributeModifier<T> {applyNormalAttribute?(instance: T): void;applyPressedAttribute?(instance: T): void;applyFocusedAttribute?(instance: T): void;applyDisabledAttribute?(instance: T): void;applySelectedAttribute?(instance: T): void;}

举例

文字描述比较抽象,下面举例代码来讲解:

  • 我们可以新建个目录modifier,新建个文件index.ets,封装一个作用于 Button 组件的样式类,给它添加一些样式,如下:
export class ButtonModifier implements AttributeModifier<ButtonAttribute> {applyNormalAttribute(instance: ButtonAttribute): void {instance.width(150).height(50).fontSize(20).backgroundColor(Color.Orange)}
}
  1. 第一步:用 AttributeModifier 接口定义了一个 ButtonModifier 样式类
  2. 第二步:再实现 applyNormalAttribute 设置默认态样式:包括宽度、高度、字体等
  • 在组件文件中使用
import { ButtonModifier } from './modifier/index'@Entry
@Component
struct Index {@State buttonModifier: ButtonModifier = new ButtonModifier()build() {Column() {Button('按钮').attributeModifier(this.buttonModifier)}.width('100%')}
}

效果如下:

img.png

这样我们就实现了一个对 Button 组件的样式封装,并且支持导出,跨文件使用

支持同时设置多个场景的样式

上面给 Button 组件增加了“默认态”的样式,可以在这基础上继续增加“按压态”的样式,就是按钮按下时的样式,如下:

  • 按钮按下的时候:增加边框,边框颜色等
export class ButtonModifier2 implements AttributeModifier<ButtonAttribute> {applyNormalAttribute(instance: ButtonAttribute): void {instance.width(150).height(80).fontSize(20).backgroundColor(Color.Orange)}applyPressedAttribute(instance: ButtonAttribute): void {instance.borderWidth(5).borderColor(Color.Blue).borderStyle(BorderStyle.Solid).backgroundColor('#17A98D')}
}
  • 在组件中引用
import { ButtonModifier2 } from './modifier/index'@Entry
@Component
struct Index {@State buttonModifier: ButtonModifier2 = new ButtonModifier2()build() {Column() {Button('按钮').attributeModifier(this.buttonModifier)}.width('100%')}
}

效果如下:

接口中支持传参和业务逻辑

ButtonModifier3 样式类中,定义一个 isClick 变量,来区分按钮是否点击过,然后分别对点击和没有点击的情况下增加样式,如下:

export class ButtonModifier3 implements AttributeModifier<ButtonAttribute> {isClick: boolean = falseconstructor(flag?: boolean) {this.isClick = !!flag}applyNormalAttribute(instance: ButtonAttribute): void {if (this.isClick) {instance.backgroundColor('#707070')} else {instance.borderColor('#707070').borderWidth(2).backgroundColor('#17A98D')}}
}
  • 在组件中调用
import { ButtonModifier3 } from './modifier/index'@Entry
@Component
struct Index {@State buttonModifier: ButtonModifier3 = new ButtonModifier3()// @State buttonModifier: ButtonModifier3 = new ButtonModifier3(true)build() {Column() {Button('按钮').attributeModifier(this.buttonModifier).onClick(() => {this.buttonModifier.isClick = !this.buttonModifier.isClick})}.width('100%')}
} 

效果如下:

总结

  • 注意事项

我们在实现 AttributeModifier<T> 接口的实例,T 必须指定为组件对应的 Attribute类型,或者是CommonAttribute,如下:

// 作用于 Button 组件,就要传入 ButtonAttribute
export class Modifier1 implements AttributeModifier<ButtonAttribute> {applyNormalAttribute?(instance: ButtonAttribute): void;
}// 作用于 TextInput 组件,就要传入 TextInputAttribute
export class Modifier2 implements AttributeModifier<TextInputAttribute> {applyNormalAttribute?(instance: ButtonAttribute): void;
}
  • @Style 和 @Extend 和 AttributeModifier 三者对比
能力 @Styles @Extend AttributeModifier
跨文件导出 不支持 不支持 支持
通用属性设置 支持 支持 支持
通用事件设置 支持 支持 部分支持
组件特有属性设置 不支持 支持 部分支持
组件特有事件设置 不支持 支持 部分支持
参数传递 不支持 支持 支持
多态样式 支持 不支持 支持
业务逻辑 不支持 不支持 支持

最后

如果大家有不理解的地方可以留言,或自行阅读文档 文档地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/881987.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

滑坡监测识别摄像机

滑坡监测摄像机能够24小时不间断地拍摄特定区域,并将实时画面传输到控制中心。这一功能确保了对潜在滑坡区域的持续关注,可以第一时间发现异常情况。通过集成深度学习算法,这些摄像机可以自动分析捕捉到的视频数据。例如,当检测到土壤位移或岩石崩落时,系统会立即发出警报…

『玩转Streamlit』--会话状态管理

在Web应用开发中,会话管理是一个至关重要的概念,它能够帮助开发者追踪用户在应用中的行为和状态,从而为用户提供更加个性化、连贯且高效的交互体验。 Streamlit作为一个简单而强大的用于快速构建和部署数据科学和机器学习项目,也提供了强大的会话状态管理功能,即st.sessio…

深度学习四大名著-蜥蜴书-《机器学习实战:基于Scikit-Learn、Keras和TensorFlow 原书第3版 中文版+英文版》PDF、EPUB免费下载

深度学习四大名著全新升级版,为机器学习落地实践提供翔实指导,Keras之父鼎力推荐。 这本机器学习畅销书基于TensorFlow 2和Scikit-Learn的新版本进行了全面更新,通过具体的示例、非常少的理论和可用于生产环境的Python框架,从零帮助你直观地理解并掌握构建智能系统所需要的…

看板软件在酒店行业:从任务分配到跨部门协作的全面升级

酒店行业通过使用看板软件进行项目管理,可以实现任务的可视化管理、提高跨部门协作效率、优化工作流程以及持续监控与优化项目进展。这有助于酒店提升运营效率、服务质量以及客户满意度。酒店行业使用看板软件进行项目管理,可以有效提升运营效率和服务质量。以下是如何在酒店…

DevOps和它的朋友们——聊聊其他 “Ops”(一)

DevOps不仅仅是将敏捷开发概念与IT运维相结合,还简化了在云环境中开发和部署应用程序的过程,从而使开发生命周期大大缩短。大家好,我是陈哥,今天想和大家聊聊DevOps与其他“Ops”。 DevOps不仅仅是将敏捷开发概念与IT运维相结合,还简化了在云环境中开发和部署应用程序的过…

进程权限 - 降低子进程权限(windows)

在 Windows 系统中,管理员权限和非管理员权限运行的程序之间不能使用 Windows 提供的通信机制进行通信。对于部分文件夹(ProgramData),管理员权限创建的文件是不能以非管理员权限修改和删除的。 然而,一个进程运行之后启动的子进程,会继承当前进程的 UAC 权限;于是有时我…

java安全中的类加载

java安全中的类加载本文所涉及的内容仅供参考与教育目的,旨在普及网络安全相关知识。其内容不代表任何机构、组织或个人的权威建议,亦不构成具体的操作指南或法律依据。作者及发布平台对因使用本文信息直接或间接引发的任何风险、损失或法律纠纷不承担责任。对应的代码我发在…

cvat nuclio serverless pip install安装失败

cvat nuclio serverless 安装自动标注插件失败./serverless/deploy_cpu.sh serverless/onnx/WongKinYiu/yolov7主要pip安装失败的原因是部分依赖包不能够在大陆下载 只需要将function.yaml内的脚本添加依赖加速即可-i https://pypi.tuna.tsinghua.edu.cn/simple

Qt写Word文档-Windows

电脑没有安装微软的office,安装的是wps,用的是 QAxObject,所以只支持Windows系统一、pro文件添加 axcontainer 二、实现代码#include <QAxObject> #include <QDebug> // 创建Word应用程序对象 QAxObject* word = new QAxObject("kwps.Application");…

绝了,一招解决DeepSeek 提示“服务器繁忙,请稍后再试” 卡顿问题!(保姆级教程)

大家好,我是狂师。 现在 AI 圈里讨论最多的话题就是:"国产之光DeepSeek了"。 但用过的人也知道,是真的卡。动不动就提示:“服务器繁忙,请稍后再试”用官方App或网页版,估计10条回复中至少有8条会卡爆。对于重度使用的我来讲,经常会被官网的卡顿搞得差点吐血。…

揭秘 Sdcb Chats 如何解析 DeepSeek-R1 思维链

在上一篇文章中,我介绍了 Sdcb Chats 如何集成 DeepSeek-R1 模型,并利用其思维链(Chain of Thought, CoT)功能增强 AI 推理的透明度。DeepSeek-R1 强大的思维链能力给用户留下了深刻印象。本文将深入剖析 Sdcb Chats 实现这一功能的技术细节,重点介绍如何基于 OpenAI .NET…

全网最全的DeepSeek的使用指导资源,拿去用来操作其他的大模型也一样有用,你去找付费培训不如打赏我一毛

最近全网都在为火热的DeepSeek疯狂,不少商家培训都是出了付费培训,不少人都上当受骗。我就搜刮全网最全的使用,供大家使用,有使用文档,有提示词培训,有视频,应有尽有,现在我们就开始吧! 一、如何使用提示词 DeepSeek官网提供了很全面的提示词规则手册,包含了13个方向…