自学鸿蒙HarmonyOS的ArkTS语言<五>attributeModifier动态属性和用attributeModifier封装公共组件

发布于:2024-07-12 ⋅ 阅读:(189) ⋅ 点赞:(0)

【官方文档传送门】

一、抽取组件样式
class MyModifier implements AttributeModifier<ButtonAttribute> {
  applyNormalAttribute(instance: ButtonAttribute): void {
    instance.backgroundColor(Color.Black)
    instance.width(200)
    instance.height(50)
    instance.margin(10)
    instance.labelStyle({
      font: {
        size: 20,
        style: FontStyle.Italic,
        weight: FontWeight.Bold
      },
      maxLines: 2  // 文字多了可以设置行数
    })
  }

  // 按下
  applyPressedAttribute(instance: ButtonAttribute): void {
    instance.backgroundColor(Color.Green)
  }
}

...

@State myModifier1: MyModifier = new MyModifier()

build() {
    Column(){
      Button('我是用动态属性设置的按钮我是用动态属性设置的按钮')
     	.attributeModifier(this.myModifier1)
    }
}
        

在这里插入图片描述

二、根据条件设置组件属性
class MyModifier2 implements AttributeModifier<ButtonAttribute> {
  isDark: boolean = false

  applyNormalAttribute(instance: ButtonAttribute): void {
    if (this.isDark) {
      instance.backgroundColor(Color.Black)
    } else {
      instance.backgroundColor(Color.Blue)
    }
  }
}
...

@State myModifier2: MyModifier2 = new MyModifier2()

build() {
    Column(){
      Button('我是动态改变属性按钮')
        .margin(10)
        .attributeModifier(this.myModifier2)
        .onClick(() => {
          this.myModifier2.isDark = !this.myModifier2.isDark
        })
    }
}

注意:attributeModifier不能通过state感知变化

class MyModifier3 extends  CommonModifier {

  applyNormalAttribute(instance: CommonAttribute): void {
    super.applyNormalAttribute?.(instance)
  }
}
...
@State width1: number = 250
// 不能通过绑定state的形式感知数据变化
@State myModifier3: CommonModifier = new MyModifier3().width(this.width1)

build() {
    Column(){
      Button('我是改变text的width按钮')
        .margin(10)
        .onClick(() => {
          this.width1++ // width1变化了,但是text的attributeModifier的width不会变
        })
      Text('我是text,希望attributeModifier通过state感知变化,然而并不能')
        .padding(10)
        .fontColor(Color.White)
        .backgroundColor(Color.Black)
        .attributeModifier(this.myModifier3)
    }
}
三、通过调实例方法动态改变属性
class MyModifier4 extends CommonModifier {

  applyNormalAttribute(instance: CommonAttribute): void {
    super.applyNormalAttribute?.(instance) // 必须有,否则实例化的myModifier4上的padding无效
  }

  public setGroup1():void {
    this.borderStyle(BorderStyle.Dashed)
    this.borderWidth(8)
  }

  public setGroup2():void {
    this.borderStyle(BorderStyle.Dashed)
    this.borderWidth(0)
  }
}

@Component
struct MyText1 {
  @Link modifier : CommonModifier

  build(){
    Text('我是text,是通过modifier方法改变属性的')
      .fontColor(Color.White)
      .backgroundColor(Color.Brown)
      .attributeModifier(this.modifier as MyModifier4)
  }
}
...
index : number = 0
@State myModifier4: CommonModifier = new MyModifier4().padding(10)

build(){
    Button('我是调用modifier实例方法改变text属性的')
      .margin(10)
      .onClick(() => {
        this.index++
        if(this.index %2 === 1){
          (this.myModifier4 as MyModifier4).setGroup1()
        } else {
          (this.myModifier4 as MyModifier4).setGroup2()
        }
      })

    // 这种写法不行 ????
    Text('我是text,是通过modifier方法改变属性的')
      .fontColor(Color.White)
      .backgroundColor(Color.Brown)
      .attributeModifier(this.myModifier4)

    // 必须封装成组件才行
    MyText1({modifier:this.myModifier4})
}
四、封装公共组件

A、单一系统组件的公共组件 - 提供方创建 AttributeModifier 类,使用方在组件上用类的实例作为attributeModifier属性的参数传入: Button(‘xxx’).attributeModifier(类的实例)

class MyModifier5 implements  AttributeModifier<ButtonAttribute> {
  private buttonType: ButtonType  = ButtonType.Normal
  private w: number = 50
  applyNormalAttribute(instance: ButtonAttribute): void {
    instance.type(this.buttonType)
    instance.width(this.w)
    instance.margin(10)
  }

  public setStyle(type: ButtonType): MyModifier5 {
    this.buttonType = type
    return this
  }

  public setWidth(w: number): MyModifier5 {
    this.w = w
    return this
  }
}

...

// 单个系统组件封装成公共组件
@State myModifier5: MyModifier5 = new MyModifier5().setWidth(300).setStyle(ButtonType.Capsule)
@State myModifier5_1: MyModifier5 = new MyModifier5().setWidth(200)

build(){
  Button('我是单一的公共组件')
    .attributeModifier(this.myModifier5)
  Button('我是单一的公共组件2')
    .attributeModifier(this.myModifier5_1)
}

在这里插入图片描述

B、多个系统组件组合的公共组件 - 提供方只要提供组件,并接收外部传入的 attributeModifie属性值,使用方要创建AttributeModifier类,并把实例作为参数传入组件

class ImageModifier implements AttributeModifier<ImageAttribute> {
  private imgW: Length = 0
  private imgH: Length = 0

  constructor(width: Length, height: Length) {
    this.imgW = width
    this.imgH = height
  }
  width(width: Length) {
    this.imgW = width
    return this
  }
  height(height: Length) {
    this.imgH = height
    return this
  }

  applyNormalAttribute(instance: ImageAttribute): void {
    instance.width(this.imgW)
    instance.height(this.imgH)
  }
}

class TxtModifier implements AttributeModifier<TextAttribute> {
  applyNormalAttribute(instance: TextAttribute): void {
    instance.fontSize(20)
  }
}

@Component
struct MyTextImage1 {
  @Prop imgAtt : AttributeModifier<ImageAttribute>
  @Prop txtAtt: AttributeModifier<TextAttribute>
  @Prop imgUrl: ResourceStr
  @Prop text: string

  build(){
    Column() {
      Image(this.imgUrl).attributeModifier(this.imgAtt)
      Text(this.text).attributeModifier(this.txtAtt)
    }
  }
}

...
build(){
  // 多个不同系统组件封装成公共组件
  imageModifier: ImageModifier = new ImageModifier(100, 100)
  txtModifier: TxtModifier = new TxtModifier()

  MyTextImage1({
    imgAtt: this.imageModifier,
    txtAtt: this.txtModifier,
    imgUrl: $r('app.media.book'),
    text: '我是多个系统组件封装的公共组件'
  })
}

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到