【官方文档传送门】
一、抽取组件样式
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: '我是多个系统组件封装的公共组件'
})
}