鴻蒙開發(fā)筆記-5-裝飾器之@Styles裝飾器,@Extend裝飾器,stateStyles多態(tài)樣式,@AnimatableExtend裝飾器

一、@Styles裝飾器:組件級樣式復(fù)用

1. 核心特性

@Styles裝飾器是ArkUI框架中實現(xiàn)樣式復(fù)用的基礎(chǔ)工具,支持組件內(nèi)定義全局定義兩種模式。組件內(nèi)定義的@Styles方法可以訪問組件的狀態(tài)變量(如@State),而全局定義需添加function關(guān)鍵字且不支持狀態(tài)綁定。其優(yōu)先級遵循組件內(nèi)樣式 > 全局樣式 > 原生默認樣式

2. 應(yīng)用場景

// 全局樣式(不支持狀態(tài)訪問)
@Styles function globalStyle() {
  .width(150)
  .height(100)
  .backgroundColor(Color.Pink)
}

@Component struct CustomComponent {
  @State private btnHeight: number = 50
  
  // 組件內(nèi)動態(tài)樣式
  @Styles btnStyle() {
    .height(this.btnHeight)
    .backgroundColor('#FF4081')
    .onClick(() => this.btnHeight = 80)
  }

  build() {
    Column() {
      Button('全局樣式').globalStyle()
      Button('動態(tài)樣式').btnStyle()
    }
  }
}

限制:僅支持通用屬性/事件,不支持參數(shù)傳遞。


二、@Extend裝飾器:組件能力擴展

1. 核心優(yōu)勢

@Extend裝飾器通過參數(shù)化配置私有屬性支持實現(xiàn)組件擴展。其特點包括:

  • 支持目標(biāo)組件的私有屬性(如Text的fontColor
  • 允許傳遞函數(shù)參數(shù)實現(xiàn)事件綁定
  • 支持鏈?zhǔn)秸{(diào)用組合多個擴展方法。

2. 典型應(yīng)用

// 擴展Text組件樣式
@Extend(Text) 
function highlightText(size: number, color: Color) {
  .fontSize(size)
  .fontColor(color)
  .textShadow({ radius: 2, color: Color.Black })
}

// 帶事件處理的擴展
@Extend(Button) 
function animatedButton(onClick: () => void) {
  .scale({ x: 0.95, y: 0.95 })
  .onClick(onClick)
}

// 使用示例
Text('重要提示').highlightText(24, Color.Red)
Button('提交').animatedButton(() => submitForm())

三、stateStyles:動態(tài)狀態(tài)響應(yīng)

1. 狀態(tài)類型體系

狀態(tài)類型 觸發(fā)條件 典型組件
normal 默認狀態(tài) 所有組件
pressed 按壓狀態(tài)(觸摸/鼠標(biāo)按下) Button
focused 獲焦?fàn)顟B(tài)(Tab鍵導(dǎo)航) TextInput
disabled 禁用狀態(tài) Switch/Button
selected 選中狀態(tài) TabBar/Checkbox

2. 實現(xiàn)方案

@Component struct StatefulComponent {
  @Styles pressedStyle() {
    .backgroundColor('#FF5252')
    .scale({ x: 0.95, y: 0.95 })
  }

  build() {
    Button('動態(tài)按鈕')
      .stateStyles({
        normal: { 
          .backgroundColor('#2196F3') 
        },
        pressed: this.pressedStyle,
        disabled: {
          .opacity(0.5)
          .backgroundColor('#BDBDBD')
        }
      })
  }
}

進階技巧:與@State變量聯(lián)動實現(xiàn)動態(tài)樣式切換。


四、@AnimatableExtend:動畫屬性擴展

1. 實現(xiàn)原理

通過實現(xiàn)AnimatableArithmetic接口定義數(shù)值運算規(guī)則,使不可動畫屬性(如Polyline的points)支持動畫效果。

2. 開發(fā)實踐

// 自定義動畫向量類型
class Vector2D implements AnimatableArithmetic<Vector2D> {
  x: number = 0
  y: number = 0
  
  plus(rhs: Vector2D): Vector2D {
    return new Vector2D(this.x + rhs.x, this.y + rhs.y)
  }
  // 實現(xiàn)其他運算符...
}

// 擴展Polyline組件
@AnimatableExtend(Polyline) 
function animPath(points: Vector2D[]) {
  .points(points.map(p => [p.x, p.y]))
}

@Component struct PathAnimation {
  @State path: Vector2D[] = [new Vector2D(0,0), new Vector2D(100,100)]
  
  build() {
    Polyline()
      .animPath(this.path)
      .animation({ duration: 2000, curve: Curve.EaseInOut })
      .onClick(() => {
        this.path = [new Vector2D(200,50), new Vector2D(300,200)]
      })
  }
}

適用場景:路徑動畫、顏色漸變、自定義布局動畫。


五、對比

特性 @Styles @Extend stateStyles @AnimatableExtend
核心目的 樣式復(fù)用 組件擴展 狀態(tài)響應(yīng) 動畫擴展
定義位置 組件/全局 全局 組件內(nèi) 全局
參數(shù)支持 ? ? ? ?
狀態(tài)感知 組件內(nèi)樣式支持 ? ? ?
動畫支持 ? ? ? ?
私有屬性訪問 ? ? ? ?

六、總結(jié)

  • 基礎(chǔ)樣式(@Styles) :定義全局基礎(chǔ)樣式(如按鈕尺寸、字體規(guī)范)
  • 組件擴展(@Extend) :創(chuàng)建組件變體(如帶圖標(biāo)的按鈕)
  • 狀態(tài)樣式(stateStyles) :處理交互狀態(tài)(按壓/禁用樣式)
  • 動畫擴展(@AnimatableExtend):實現(xiàn)復(fù)雜動效

性能優(yōu)化建議

  • 避免在@Styles中進行復(fù)雜計算
  • stateStyles建議使用純數(shù)值狀態(tài)變量
  • 優(yōu)先使用系統(tǒng)內(nèi)置動畫屬性,必要時再使用自定義動畫

綜合示例

// 樣式分層架構(gòu)
@Styles function baseButton() { 
  .padding(10).borderRadius(5) 
}

@Extend(Button)
function primaryButton() {
  baseButton()
  .backgroundColor(BrandColor.Primary)
  .stateStyles({
    pressed: {
      .opacity(0.8)
    }
  })
}

// 實現(xiàn)動畫按鈕
@AnimatableExtend(Button)
function scaleButton(scale: number) {
  .scale({ x: scale, y: scale })
}

@Entry
@Component struct SmartButtonPage {
  @State btnScale: number = 1

  build() {
    Column() {
      Button('智能按鈕')
        .primaryBtn()
        .scaleButton(this.btnScale)
        .animation({ curve: Curve.Spring })
        .onClick(() => {
          this.btnScale = this.btnScale > 1 ? 1 : 1.2
        })
    }
  }
}

我是今陽,如果想要進階和了解更多的干貨,歡迎關(guān)注wxgzh “今陽說” 接收我的最新文章

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容