ETS装饰器学习之Extend、CustomDialog 原创
在学习声明式UI框架ArkUI的过程中,会遇到装饰器的概念,不管是简单的示例页面还是复杂的大程序,都离不开装饰器的使用,为了帮助自己对装饰器有一个基本的了解,并能够熟练的使用,所以专门针对ets装饰器系统的学习了一下,并整理成简单的笔记,以便健忘的我随时回来复习一下。
本文主要介绍Extend和CustomDialog,Extend用来专门针对内置组件定义新方法,CustomDialog则用来自定义弹窗,系统弹窗不满足用户需求的情况下,就可以使用这个。
@Extend
@Extend装饰器将新的属性函数添加到内置组件上,如Text、Column、Button等。通过@Extend装饰器可以快速的扩展原生组件。@Extend装饰器不能用在自定义组件struct定义框内。
通过对内置组件进行二次封装,把需要的属性设置封装在一个方法内,可以减少对内置组件的重复设置。
示例代码:
@Entry
@Component
struct Main {
build() {
Column(){
Text("Introduction")
.titleFormat()
Text("ArkUI is a UI development framework that provides what you'll need to develop application UIs.")
.contentFormat()
Row() {
Button('Ok')
.positiveButton()
Button('Cancel')
.negativeButton()
}
.width('100%')
.justifyContent(FlexAlign.SpaceEvenly)
.margin({top:100})
}
.width('100%')
.height('100%')
.padding(10)
.topCenter()
}
}
@Extend(Text) function titleFormat() {
.fontColor(Color.Black)
.fontSize(30)
.fontWeight(FontWeight.Bold)
.align(Alignment.Start)
.width('100%')
.margin({bottom:10})
}
@Extend(Text) function contentFormat() {
.fontColor(Color.Black)
.fontSize(15)
.fontWeight(FontWeight.Normal)
.align(Alignment.Start)
.width('100%')
}
@Extend(Column) function topCenter() {
.justifyContent(FlexAlign.Start)
.align(Alignment.Center)
}
@Extend(Button) function positiveButton() {
.backgroundColor(Color.Blue)
.fontColor(Color.White)
.width(100)
}
@Extend(Button) function negativeButton() {
.backgroundColor(Color.Gray)
.fontColor(Color.White)
.width(100)
}
效果预览:
上面示例,分别在Text、Column、Button组件自定义了新方法,通过这种自定义,让开发可以更加简便高效。
Text自定义的titleFormat属性函数,快速设置文本为标题格式,contentFormat快速设置文本为正文格式,
Column自定义的topCenter属性函数,设置顶部对齐,居中显示。
Button自定义的positiveButton和negativeButton属性函数,分别定义了主要按钮和次要按钮。
@CustomDialog
@CustomDialog装饰器用于装饰自定义弹窗,使得弹窗可以动态设置样式。
我们采用临摹的方式,做一个类似华为手机上的删除确认框,原对话框如下
首先使用系统标准弹窗AlertDialog做一个删除窗口,
示例代码:
@Entry
@Component
struct Index {
build() {
Column() {
Button("Show Dialog")
.onClick(() => {
AlertDialog.show({
title: "是否删除此文件?",
message: "移动到最近删除后最长保留30天,之后将永久删除。",
alignment: DialogAlignment.Bottom,
primaryButton: {
value: '取消',
fontColor: Color.Blue,
action: () => {
console.info('点击了取消')
}
},
secondaryButton: {
value: '删除',
fontColor: Color.Red,
action: () => {
console.info('点击了删除')
}
},
})
})
.width('50%')
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
效果预览:
弹出窗口很简单,但也有很多局限,不能加复选框,字体也不能调节,所以很多时候不能满足开发者的要求,我们使用CustomDialog重新做一个删除对话框。
示例代码:
@Preview
@CustomDialog
struct CustomDelDialog {
private controller: CustomDialogController;
build() {
Stack() {
Column() {
Text('是否删除此文件?')
.fontSize(26)
.margin({top: 15})
.width('100%')
Text('移动到最近删除后最长保留30天,之后将永久删除。')
.fontSize(20)
.margin({top: 20})
.width('100%')
Row() {
Checkbox({name: 'recent'})
.size({width: 10, height:10})
// .backgroundColor(Color.Green)
.margin(0)
.padding(0)
Text('移动到最近删除')
.fontSize(20)
.margin({left: 5})
}
.width('100%')
.justifyContent(FlexAlign.Start)
.align(Alignment.Center)
.margin({top:20})
Row() {
Button ("取消")
.onClick(() => {
console.log("点击了取消")
this.controller.close()
})
.backgroundColor(Color.White)
.fontColor(Color.Blue)
.fontSize(20)
Button ("删除")
.onClick(() => {
console.log("点击了删除")
this.controller.close()
})
.backgroundColor(Color.White)
.fontColor(Color.Red)
.fontSize(20)
}
.height(60)
.width('100%')
.justifyContent(FlexAlign.SpaceAround)
.margin({top:30})
}
.backgroundColor("#e6ffffff")
.borderRadius(20)
.justifyContent(FlexAlign.Start)
.padding(20)
}
.padding({left: 20, right: 20})
.width("100%")
}
}
@Entry
@Component
struct Index {
controller: CustomDialogController = new CustomDialogController({
builder: CustomDelDialog(),
cancel: () => {
console.log("cancel")
},
autoCancel: false,
customStyle: true,
alignment: DialogAlignment.Bottom,
offset: {dx:0, dy: -20}
});
build() {
Column() {
Button("Show Dialog")
.onClick(() => {
this.controller.open()
})
.width('50%')
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
效果预览:
总结一下,添加CustomDialog一共分两步:
- 添加一个@CustomDialog修饰的struct类,内部定义一个CustomDialogController类型的controller变量,不用初始化,在build函数中,按照需要构建弹出窗口的界面。
- 在调用弹出窗口的Component内也定义一个CustomDialogController类型的内部变量,需要初始化,并指定参数中builder变量为第一步定义的struct类。