在 API 18(HarmonyOS 5)开始,官方新增了 AttributeModifierAttributeUpdater 两套新的属性更新机制,它们主要解决:

  • UI 属性动态更新
  • 样式复用
  • Modifier 组合
  • 高性能局部刷新
  • 动态主题
  • 动态组件能力

本文将全面解析它们的设计思想及最佳实践。


一、为什么需要 AttributeModifier?

先来看以前 ArkUI 是如何修改属性的。

例如:


Text("HarmonyOS")
  .fontSize(20)
  .fontColor(Color.Blue)
  .fontWeight(FontWeight.Bold)

如果想根据状态修改:


Text("HarmonyOS")
  .fontSize(this.big ? 30 : 20)
  .fontColor(this.dark ? Color.White : Color.Black)

这样写没问题。

但是:

如果有几十个组件需要统一切换主题:


Button
Image
Text
Column
Row
List
Grid

每一个都要写:


fontColor(...)
backgroundColor(...)
opacity(...)

代码会迅速膨胀。

例如:


if (theme == Dark) {

}

else {

}

重复数百次。

于是官方提出:

Modifier(修饰器)

类似:

Flutter


Theme
Decoration
TextStyle

Compose


Modifier

SwiftUI


ViewModifier

HarmonyOS 终于也拥有了自己的 Modifier。


二、什么是 AttributeModifier?

官方定义:

AttributeModifier 用于统一管理组件 Attribute。

它可以:

  • 修改属性
  • 批量设置属性
  • 动态切换属性
  • 封装样式
  • 响应状态变化

可以理解成:


一个专门修改组件属性的对象

例如:


Button

↓

Modifier

↓

设置:

fontColor
fontSize
width
height
background
padding
margin
...

三、AttributeModifier 架构

整体关系:


State

↓

AttributeUpdater

↓

AttributeModifier

↓

ArkUI Component

↓

RenderNode

更新流程:


状态变化

↓

Updater收到通知

↓

Modifier修改Attribute

↓

Diff

↓

Render

因此:

Modifier 不直接参与绘制。

它只是:


更新Attribute

真正绘制还是 RenderNode。


四、第一个 AttributeModifier

例如:


class MyModifier extends AttributeModifier<ButtonAttribute> {

}

然后:


Button("登录")
  .attributeModifier(new MyModifier())

Modifier 就会接管 Button 属性。


五、AttributeModifier 生命周期

官方执行流程:


创建

↓

绑定组件

↓

applyNormalAttribute()

↓

状态变化

↓

applyPressedAttribute()

↓

恢复

↓

applyNormalAttribute()

↓

销毁

因此:

Modifier 是长期存在的。

不是每次刷新创建。


六、常用 API

主要方法:


applyNormalAttribute()

applyPressedAttribute()

applyFocusedAttribute()

applyDisabledAttribute()

applySelectedAttribute()

applyHoveredAttribute()

例如:


class ButtonModifier extends AttributeModifier<ButtonAttribute> {

    applyNormalAttribute(attribute: ButtonAttribute) {

    }

}

七、Normal 状态

例如:


class MyModifier extends AttributeModifier<ButtonAttribute>{

    applyNormalAttribute(attr){

        attr.backgroundColor(Color.Blue)

        attr.fontColor(Color.White)

    }

}

效果:


正常:

蓝色背景

白色字体

八、Pressed 状态

例如:


applyPressedAttribute(attr){

    attr.backgroundColor(Color.Red)

}

按下立即切换。

无需:


@State

if

setState

全部框架完成。


九、Focused 状态

TV

车机

PC

大量使用:


applyFocusedAttribute(attr){

    attr.border({
        width:2,
        color:Color.Yellow
    })

}

焦点来了:

自动更新。


十、Disabled 状态

例如:


applyDisabledAttribute(attr){

    attr.opacity(0.4)

}

无需:


enabled?

opacity?

统一管理。


十一、Selected 状态

例如:


Tab

Menu

List

Grid

可以:


applySelectedAttribute(attr){

    attr.backgroundColor(Color.Green)

}

十二、Hovered 状态

PC:


applyHoveredAttribute(attr){

    attr.scale({
        x:1.1,
        y:1.1
    })

}

鼠标进入:

自动放大。


十三、AttributeUpdater

Modifier:

负责:


怎么修改

Updater:

负责:


什么时候修改

这是最大的区别。


十四、Updater 工作流程


State

↓

AttributeUpdater

↓

Modifier

↓

Component

因此:

Updater 更像:


观察者

十五、为什么需要 Updater?

以前:


@State

变化:

整个 Builder 重建。

现在:


State

↓

Updater

↓

仅修改Attribute

Builder 不需要重建。

性能提升明显。


十六、Updater 示例

例如:


class MyUpdater extends AttributeUpdater<ButtonAttribute> {

}

然后:


Button("登录")
    .attributeUpdater(new MyUpdater())

十七、监听状态

例如:


updateAttribute(attr){

}

每次:


State变化

↓

updateAttribute

调用。


十八、Modifier 与 Updater 的区别

AttributeModifier AttributeUpdater
修改属性 驱动属性更新
管理状态样式 响应状态变化
类似 CSS 类似 Observer
长期存在 响应数据

一句话:


Modifier负责怎么画

Updater负责什么时候画

十九、动态主题

例如:


class ThemeModifier extends AttributeModifier<TextAttribute>{

}

切换:


Dark

↓

White

↓

Blue

统一刷新。


二十、动态字体

例如:


attr.fontSize(theme.fontSize)

即可:


所有组件

统一字号

二十一、动画结合

例如:


animateTo(()=>{
    theme.dark=true
})

Modifier:

自动更新:


background

font

opacity

二十二、Modifier 组合

可以:


ThemeModifier

+

PaddingModifier

+

AnimationModifier

多个组合。

类似:

Compose Modifier。


二十三、性能优势

以前:


State变化

↓

Builder

↓

Component

↓

Diff

↓

Render

现在:


State

↓

Updater

↓

Attribute

↓

Diff

↓

Render

Builder:

不用重建。


二十四、实际案例:统一按钮样式


class PrimaryButtonModifier extends AttributeModifier<ButtonAttribute> {

  applyNormalAttribute(attr: ButtonAttribute) {
    attr.backgroundColor('#007DFF')
    attr.fontColor(Color.White)
    attr.borderRadius(12)
    attr.height(48)
  }

  applyPressedAttribute(attr: ButtonAttribute) {
    attr.backgroundColor('#005FCC')
    attr.scale({ x: 0.96, y: 0.96 })
  }

  applyDisabledAttribute(attr: ButtonAttribute) {
    attr.opacity(0.4)
  }
}

使用:


Button("提交")
  .attributeModifier(new PrimaryButtonModifier())

优点:

  • 风格统一
  • 可复用
  • 易维护
  • 状态清晰

二十五、动态主题案例


@Observed
class ThemeModel {
  dark: boolean = false
}

class ThemeTextModifier extends AttributeModifier<TextAttribute> {
  constructor(private theme: ThemeModel) {
    super()
  }

  applyNormalAttribute(attr: TextAttribute) {
    attr.fontColor(this.theme.dark ? Color.White : Color.Black)
    attr.backgroundColor(this.theme.dark ? Color.Black : Color.White)
  }
}

当主题状态变化时,可配合 AttributeUpdater 或响应式状态,仅更新文本属性,而无需重建整个页面。


二十六、最佳实践

推荐将 AttributeModifier 用于样式定义,将 AttributeUpdater 用于数据驱动更新,两者职责分离:

  • Modifier:封装颜色、字号、边框、圆角、阴影、间距等视觉样式。
  • Updater:监听状态变化,仅更新受影响的属性。
  • 业务逻辑:仍放在 @State@Observed@ObjectLink 等响应式模型中,不要混入 Modifier。

对于大型项目,可以建立统一的样式体系,例如:


common/
 ├── modifier/
 │    ├── ButtonModifier.ets
 │    ├── TextModifier.ets
 │    ├── CardModifier.ets
 │    └── ThemeModifier.ets
 ├── updater/
 │    ├── ThemeUpdater.ets
 │    ├── LocaleUpdater.ets
 │    └── UserStateUpdater.ets
 └── theme/
      ├── Colors.ets
      ├── Typography.ets
      └── Dimensions.ets

这样可以做到:

  • UI 风格统一
  • 支持深色模式与动态主题
  • 降低重复代码
  • 提升组件复用性
  • 减少 Builder 重建,提高渲染性能

总结

AttributeModifierAttributeUpdater 是 HarmonyOS 5 ArkUI 在属性管理上的重要增强,它们分别负责如何修改属性何时触发属性更新。与传统依赖 Builder 重建的方式相比,这种机制更接近现代声明式 UI 框架(如 Jetpack Compose 的 Modifier、SwiftUI 的 ViewModifier),能够实现更细粒度的属性更新、更高的性能以及更好的样式复用能力。

在实际开发中,建议将它们应用于主题切换、统一样式、状态切换、交互反馈以及大型组件库建设中,以充分发挥 HarmonyOS 5 新一代 ArkUI 的响应式与高性能优势。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐