不要用@Extend和@Style了,HarmonyOS鸿蒙Next中这个库对全局属性使用的AttributeUpdater进行扩展!错过后悔一辈子!!!

不要用@Extend@Style了,HarmonyOS鸿蒙Next中这个库对全局属性使用的AttributeUpdater进行扩展!错过后悔一辈子!!!

系统API

属性更新器 (AttributeUpdater) 就是跨文件更新控件属性值。

例子:

//定义一个 MyTextModifier.ets 文件
class MyTextModifier extends AttributeUpdater<TextAttribute, TextInterface> {
  initializeModifier(instance: TextAttribute): void {
    instance.fontColor(Color.White)
    .fontSize(14)
    .border({ width: 1 })
    .textAlign(TextAlign.Center)
  }
}

//然后可以在所有页面(Component)使用:
modifier: MyTextModifier = new MyTextModifier()
build() {
    Text("Text").attributeModifier(this.modifier)
}        

这就有了Android中的theme.xml设置

除此之外,还拥有监听以下状态(按下、聚焦等)的变化:

applyNormalAttribute?(instance: T): void;
  
applyPressedAttribute?(instance: T): void;
  
applyFocusedAttribute?(instance: T): void;
  
applyDisabledAttribute?(instance: T): void;
  
applySelectedAttribute?(instance: T): void;

这就有了Android中的selector设置

所以我们只要继承AttributeUpdater后,就有以上的功能了。

但是,只要你使用过这个类,你就会发现对于一个控件只有一次设置attributeModifier的机会,如果我们有多个不同的样式,那岂不是需要分成很多个MyTextModifier?

举了个例子:对于Text我有控制fontColor、background、border三个属性,且每种属性有三种样式,在不同的场景需要自由组合,那请大家想想这里自定义多少个MyTextModifier?

这显然不合理!

对AttributeUpdater进行扩展

因此,就有了Attribute Style这个开源库。其实库的原理也非常简单,使用SAdapter对所有单独样式进行添加监听,当AttributeUpdater子类SAttribute发生变化时,就让SAdapter通知所有添加的样式进行刷新。

首先我们自定义一个样式,实现SStyle接口,而且只需实现自己所需要场景的方法即可,如:

export class TextColor1Style implements SStyle<TextAttribute> {
    initializeModifier(instance?: TextAttribute): void {
        instance?.fontColor('#666666')
  }
}

export class TextColor2Style implements SStyle<TextAttribute> {
    initializeModifier(instance?: TextAttribute): void {
    instance?.fontColor('#333333')
}
}

export class TextBackground1Style implements SStyle<TextAttribute> {
    initializeModifier(instance?: TextAttribute): void {
    instance?.backgroundColor('#FFFFFF')
}

接着我们使用SAdapter进行组装,最后生成SAttribute

style1 = new SAdapter<TextAttribute>()
    .addStyle(new TextColor1Style())
    .addStyle(new TextBackground1Style())
    .buildAttribute()
style2 = new SAdapter<TextAttribute>()
    .addStyle(new TextColor2Style())
    .addStyle(new TextBackground1Style())
    .buildAttribute()

build() {
     Row(){
        Text("style1").attributeModifier(this.style1)
        Text("style2").attributeModifier(this.style2)
    }
}  

这体会到这个库的威力了吧!但你别以为就仅此而已!!!

这里仅给你体现10种样式的实现方案:

private style1 = new SAdapter<TextAttribute>()
    .addStyle(new ContainStyle())
    .addStyle(new BgGreenStyle())
    .addStyle(new TextNormalStyle())
    .addStyle(new TextPressedStyle())
    .addStyle(new HoverBgStyle())
    .buildAttribute(true, true/*Hover消失交给NormalStyle处理*/)
  private style2 = new CustomTextAdapter().buildAttribute()
  private style3 = new PacketAdapter().buildAttribute()
  private style4 = new SAdapter<TextAttribute>()
    .addStyle(new TextNormalStyle())
    .addStyle(new TextPressedStyle())
    .buildAttribute(true)
  private style5 = new SAdapter<TextAttribute>()
    .addStyle(new ContainStyle())
    .addStyle({
      normalStyle(instance) {
        instance?.backgroundColor('#ff858282')
      }
    })
    .addStyle(new SelectedBgStyle())
    .buildAttribute(true, true) //this.style5.updateSelect(false) 自动走 normalStyle 样式
  private style6 = new SAdapter<TextAttribute>()
    .addStyle(new ContainStyle())
    .addStyle({
      normalStyle(instance) {
        instance?.backgroundColor('#fff58787').borderWidth(0)
      }
    })
    .addStyle(new ErrorBorderStyle())
    .buildAttribute(true, false) //this.style5.updateSelect(false) 走 errorStyle 样式,并且appear为false
  private style7 = new SAdapter<RowAttribute>()
    .addStyle(new ContainStyle())
    .addStyle({
      normalStyle(instance?: RowAttribute | undefined) {
        instance?.backgroundColor('#ff646262')
      }
    })
    .buildAttribute()
    .onHover((instance?: RowAttribute, appear?: boolean) => {
      if (appear) {
        instance?.backgroundColor('#ffd7db5a')
      } else {
        instance?.backgroundColor('#ff646262')
      }
    })
  private style8 = new CustomInputAdapter().buildAttribute()
  //使用SAttribute包裹一样的效果
  private style9 = new SAttribute<TextAttribute>(new SAdapter<TextAttribute>()
    .addStyle({
      normalStyle(instance?: TextAttribute | undefined) {
        instance?.backgroundColor('#ff6fb182').fontColor(Color.White).fontSize(14).padding(5).borderRadius(5)
      },
      disabledStyle(instance?: TextAttribute | undefined) {
        instance?.backgroundColor('#ffd7d7d7').fontColor(Color.Black)
      }
    }))
  private style10 = new CustomTextAdapter().property.buildAttribute<TextInterface>()

还扩展了对鼠标Hovered事件的处理,且对系统API存在的问题做了一些处理,比直接使用系统API少了很多莫名的问题!而且整个项目源码就500多行代码,什么概念?你花个几分钟就能熟悉了这个库了!而带来的收益至少把相同代码减少了7成!!

以下就是对@qincji/astyle开源库的简单使用,更多请看demo

AttributeStyle

介绍

HarmonyOS ArkUI的跨文件、全局公共样式,比Android中的theme.xml和selector更加健全。对Pressed、Disabled、Hovered、Focused、Selected等状态样式设置,更是PC和电视端的福音!

你还在只会用@Styles[@Extend](/user/Extend)吗?落后很多了呀,兄弟!!!这里对AttributeUpdater 进行扩展,对系统的PressedDisabledHoveredFocused以及自定义Selected等进行处理,各种状态样式可分可合 ,把自由组成发挥的淋漓尽致,很大程度减少了重复代码。

安装教程

ohpm install @qincji/astyle

使用说明

  1. 导入相关文件
import { SAdapter, xxx } from '@qincji/astyle';
  1. 在使用页面中创建
private style1 = new SAdapter<xxxAttribute>()
    .addStyle(new xxxStyle())
    .addStyle(new xxxStyle())
    .buildAttribute()
    
//或者 CustomTextAdapter 为SAdapter子类,处理所有状态样式
private style2 = new CustomTextAdapter().buildAttribute()

//或者 单独增加样式,对应SStyle和父类所有的事件
private style7 = new SAdapter<RowAttribute>()
    .addStyle(new ContainStyle())
    .addStyle({
      normalStyle(instance?: RowAttribute | undefined) {
        instance?.backgroundColor('#ff646262')
      }
    })
    .buildAttribute()

//更多使用方式请看demo源码    

主:相同属性设置后设置覆盖前设置,如.fontSize

  1. 使用,每一个对象要一一对应!(全局样式1行代码实现,而且支持所有系统组件)
Text('style1 normal & pressed & hover').attributeModifier(this.style1)

Text('style2 CustomTextAdapter').attributeModifier(this.style2)


 Row() {   }.attributeModifier(this.style7)

SState 和 (SStyle + SIState)对应关系说明

字段 对应关系 介绍
Init initializeModifier 【系统回调】初始化时(只会触发一次)
Normal normalStyle 【系统回调】正常
Pressed pressedStyle 【系统回调】 按下
Disabled disabledStyle 【系统回调】不可用
Hovered hoverStyle 【系统回调】鼠标选中状态
Focused focusStyle 【系统回调】获取焦点
Selected selectedStyle 【主动调用】 选中类型(一般配合popup使用)
Error errorStyle 【主动调用】 错误类型(一般配合input使用)
Custom customStyle 【主动调用】 自定义扩展

其中:Selected、Error、Custom为扩展类型,需要自己调用函数触发,如:

private
style2 = new CustomTextAdapter().buildAttribute()
//更新状态
this.style2.updateSelect(isAppear)

项目地址:https://gitee.com/qincji/AttributeStyle


更多关于不要用@Extend和@Style了,HarmonyOS鸿蒙Next中这个库对全局属性使用的AttributeUpdater进行扩展!错过后悔一辈子!!!的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

attributeModifier和这个有什么区别?

更多关于不要用@Extend和@Style了,HarmonyOS鸿蒙Next中这个库对全局属性使用的AttributeUpdater进行扩展!错过后悔一辈子!!!的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,推荐使用AttributeUpdater来扩展全局属性,替代传统的@Extend@StyleAttributeUpdater提供了更灵活和动态的方式来管理和更新UI组件的属性,适用于复杂场景和动态需求。通过AttributeUpdater,开发者可以更高效地控制组件的样式和行为,提升代码的可维护性和扩展性。这一新特性将显著提升开发体验,建议尽快掌握并应用。

回到顶部