我们在自定义组件的时候,无论是用 @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%')
}
}

效果如下:

这样我们就实现了一个对 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 = false constructor(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
跨文件导出 不支持 不支持 支持
通用属性设置 支持 支持 支持
通用事件设置 支持 支持 部分支持
组件特有属性设置 不支持 支持 部分支持
组件特有事件设置 不支持 支持 部分支持
参数传递 不支持 支持 支持
多态样式 支持 不支持 支持
业务逻辑 不支持 不支持 支持

最后

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

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

  1. Android开发:UI相关(一)自定义样式资源

    一.自定义样式资源:   1.在drawble中新建xml资源文件:     如果新建的xml文件没有自动放置在drawable文件夹下,就手动移动到drawable下. 2.编写样式代码: < ...

  2. Appcan开发笔记:导出Excel文件

    Appcan IDE为4.0+; appcan提供了导出文件的方法 appcan.file.write 文件会自动创建,要解决的事情是Excel用字符串输出,可以考虑 csv(逗号间隔).HTML.X ...

  3. java中使用poi导入导出excel文件_并自定义日期格式

    Apache POI项目的使命是创造和保持java API操纵各种文件格式基于Office Open XML标准(OOXML)和微软的OLE复合文档格式(OLE2)2.总之,你可以读写Excel文件使 ...

  4. input type='file'文件上传自定义样式

    使用场景: 在未使用UI库时免不了会用到各种上传文件,那么默认的上传文件样式无法达到项目的要求,因此重写(修改)上传文件样式是必然的,下面的效果是最近项目中自己写的一个效果,写出来做个记录方便以后使用 ...

  5. ReportViewer 不预览,直接导出 PDF文件

    作为笔记记着,以免以后再到处找资料 1. 在不预览的情况下导出文件 先看一个方法说明,想知道ReportViewer支持导出哪些文件类型,在Render方法说明中就有描述 // // Summary: ...

  6. 导出Excel文件

    /// <summary> /// 类说明:Assistant /// 更新网站:[url=http://www.sufeinet.com/thread-655-1-1.html]http ...

  7. 使用NPOI或EPPlus来导出Excel文件实例,可在Excel文件加密

    使用NPOI.dll组件来导出Excel文件,并设置样式,Nuget引用即可. packages\NPOI.2.1.3.1\lib\net20\NPOI.dll #region Excel prote ...

  8. ios开发--一个苹果证书怎么多次使用——导出p12文件

    为什么要导出.p12文件 当我们用大于三个mac设备开发应用时,想要申请新的证书,如果在我们的证书里,包含了3个发布证书,2个开发证书,可以发现再也申请不了开发证书和发布证书了(一般在我们的证书界面中 ...

  9. 一个苹果证书怎么多次使用(授权Mac开发)——导出p12文件

    为什么要导出.p12文件 当我们用大于三个mac设备开发应用时,想要申请新的证书,如果在我们的证书里,包含了3个发布证书,2个开发证书,可以发现再也申请不了开发证书和发布证书了(一般在我们的证书界面中 ...

  10. 游戏开发中IIS常见支持MIME类型文件解析

    游戏开发中IIS常见支持MIME类型文件解析 .apkapplication/vnd.android .ipaapplication/vnd.iphone .csbapplication/octet- ...

随机推荐

  1. 设计模式:可复用面向对象软件的基础 pdf电子书分享

    <设计模式:可复用面向对象软件的基础>是引导读者走出软件设计迷宫的指路明灯,凝聚了软件开发界几十年设计经验的结晶.四位顶尖的面向对象领域专家精心选取了最具价值的设计实践,加以分类整理和命名 ...

  2. Redis循环慢接口优化

    原慢接口 List<String> keys = new ArrayList<>(Arrays.asList("1", "2", &qu ...

  3. vue 的provide 和 inject

    1.功能说明 在开发过程中,在子组件中如何获取父组件或者祖父级的数据.这个我们之前的做法是在子组件中找到父组件实例,然后使用父组件的数据.这样其实不是很自然. 在vue 中提供了 provide 和 ...

  4. fastadmin-表格使用

    1.弹窗页面大小 <div id="toolbar" class="toolbar"> <a data-area='["90%&qu ...

  5. Flutter shared_preferrence报错

    Flutter shared_preferrence报错 在main函数中runApp之前添加**WidgetsFlutterBinding.ensureInitialized();确保初始化成功 v ...

  6. 【C#】【答卷】萌狼蓝天大二上学期期末C#考试复习卷(样题)

  7. Visual Studio - API调试与测试工具之HTTP文件

    后端开发,我们对于Api接口调试测试大致有以下方法:单元测试.Swagger.Postman. 但是每种方式也都有其局限性,几年前使用Visual Studio Code开发过一段时间,接触了REST ...

  8. Qt/C++编写超精美自定义控件(历时9年更新迭代/超202个控件/祖传原创)

    一.前言 无论是哪一门开发框架,如果涉及到UI这块,肯定需要用到自定义控件,越复杂功能越多的项目,自定义控件的数量就越多,最开始的时候可能每个自定义控件都针对特定的应用场景,甚至里面带了特定的场景的一 ...

  9. Qt音视频开发42-人脸识别客户端

    一.前言 人脸识别客户端程序,不需要和人脸识别相关的库在一起,而是通过协议通信来和人脸识别服务端通信交互,人脸识别客户端和服务端程序框架,主要是为了提供一套通用的框架,按照定好的协议,实现人脸识别的相 ...

  10. Qt编写的项目作品30-录音播放控件(雨田哥作品)

    一.功能特点 使用FMOD音频引擎开发,支持跨平台,虚拟频道,插件设计. 数字回放,多个声卡,多路输出,多路输入. 自定义回放延迟,网络特性. 支持类型:DLS.M3U.ASX.WAX.PLS.AIF ...