【HarmonyOS之旅】ArkTS语法(二)->动态构建UI元素

embedded/2024/12/30 17:38:16/

目录

uilder-toc" style="margin-left:0px;">1 -> @Builder

uilderParam8%2B-toc" style="margin-left:0px;">2 -> @BuilderParam8+

2.1 -> 引入动机

2.2 -> 参数初始化组件

2.3 -> 尾随闭包初始化组件

3 -> @Styles

4 -> @Extend

5 -> @CustomDialog


uilder">1 -> @Builder

可通过@Builder装饰器进行描述,该装饰器可以修饰一个函数,此函数可以在build函数之外声明,并在build函数中或其他@Builder修饰的函数中使用,从而实现在一个自定义组件内快速生成多个布局内容。

// Test_Builder.ets
@Component
struct CompB {@State CompValue: string = ''aboutToAppear() {console.info('CompB aboutToAppear.')}aboutToDisappear() {console.info('CompB aboutToDisappear.')}build() {Column() {Button(this.CompValue).margin(5)}}
}@Entry
@Component
struct CompA {size1: number = 100@State CompValue1: string = "Hello,CompValue1"@State CompValue2: string = "Hello,CompValue2"@State CompValue3: string = "Hello,CompValue3"// @Builder装饰的函数CompC内使用自定义组件CompB@Builder CompC(value: string) {CompB({ CompValue: value })}@Builder SquareText(label: string) {Text(label).fontSize(18).width(1 * this.size1).height(1 * this.size1)}// @Builder装饰的函数RowOfSquareTexts内使用@Builder装饰的函数SquareText@Builder RowOfSquareTexts(label1: string, label2: string) {Row() {this.SquareText(label1)this.SquareText(label2)}.width(2 * this.size1).height(1 * this.size1)}build() {Column() {Row() {this.SquareText("A")this.SquareText("B")}.width(2 * this.size1).height(1 * this.size1)this.RowOfSquareTexts("C", "D")Column() {// 使用三次@Builder装饰的自定义组件this.CompC(this.CompValue1)this.CompC(this.CompValue2)this.CompC(this.CompValue3)}.width(2 * this.size1).height(2 * this.size1)}.width(2 * this.size1).height(2 * this.size1)}
}

uilderParam8%2B">2 -> @BuilderParam8+

@BuilderParam装饰器用于修饰自定义组件内函数类型的属性(例如:@BuilderParam noParam: () => void),并且在初始化自定义组件时被@BuilderParam修饰的属性必须赋值。

2.1 -> 引入动机

当开发者创建自定义组件,并想对该组件添加特定功能时(例如在自定义组件中添加一个点击跳转操作)。若直接在组件内嵌入事件方法,将会导致所有引入该自定义组件的地方均增加了该功能。为解决此问题,引入了@BuilderParam装饰器,此装饰器修饰的属性值可为@Builder装饰的函数,开发者可在初始化自定义组件时对此属性进行赋值,为自定义组件增加特定的功能。

2.2 -> 参数初始化组件

通过参数初始化组件时,将@Builder装饰的函数赋值给@BuilderParam修饰的属性,并在自定义组件内调用该属性值。若@BuilderParam修饰的属性在进行赋值时不带参数(如:noParam: this.specificNoParam),则此属性的类型需定义为无返回值的函数(如:@BuilderParam noParam: () => void);若带参数(如:withParam: this.SpecificWithParam('WithParamA')),则此属性的类型需定义成any(如:@BuilderParam withParam: any)。

// Test_BuilderParam8+.ets
@Component
struct CustomContainer {header: string = ''@BuilderParam noParam: () => void@BuilderParam withParam: anyfooter: string = ''build() {Column() {Text(this.header).fontSize(30)this.noParam()this.withParam()Text(this.footer).fontSize(30)}}
}@Entry
@Component
struct CustomContainerUser {@Builder specificNoParam() {Column() {Text('noParam').fontSize(30)}}@Builder SpecificWithParam(label: string) {Column() {Text(label).fontSize(30)}}build() {Column() {CustomContainer({header: 'HeaderA',noParam: this.specificNoParam,withParam: this.SpecificWithParam('WithParamA'),footer: 'FooterA'})Divider().strokeWidth(3).margin(10)CustomContainer({header: 'HeaderB',noParam: this.specificNoParam,withParam: this.SpecificWithParam('WithParamB'),footer: 'FooterB'})}}
}

2.3 -> 尾随闭包初始化组件

在自定义组件中使用@BuilderParam修饰的属性时也可通过尾随闭包进行初始化(在初始化自定义组件时,组件后紧跟一个大括号“{}”形成尾随闭包场景(CustomContainer(){})。开发者可把尾随闭包看做一个容器,向其中填充内容,如在闭包内增加组件({Column(){...}),闭包内语法规范与build函数一致。此场景下自定义组件内有且仅有一个使用@BuilderParam修饰的属性。

示例:在闭包内添加Column组件并设置点击事件,在Column组件内调用@Builder修饰的specificParam函数,点击Column组件后将自定义组件CustomContainer中header的属性值由“header”改变为“changeHeader”。在初始化自定义组件CustomContainer时,尾随闭包的内容会被赋值给@BuilderParam修饰的closer属性。

// Test_BuilderParam8+.ets
@Component
struct CustomContainer {header: string = ''@BuilderParam closer: () => voidbuild() {Column() {Text(this.header).fontSize(30)this.closer()}}
}@Builder function specificParam(label1: string, label2: string) {Column() {Text(label1).fontSize(30)Text(label2).fontSize(30)}
}@Entry
@Component
struct CustomContainerUser {@State text: string = 'header'build() {Column() {CustomContainer({header: this.text,}) {Column() {specificParam('testA', 'testB')}.backgroundColor(Color.Yellow).onClick(() => {this.text = 'changeHeader'})}}}
}

3 -> @Styles

ArkTS为了避免开发者对重复样式的设置,通过@Styles装饰器可以将多个样式设置提炼成一个方法,直接在组件声明时调用,通过@Styles装饰器可以快速定义并复用自定义样式。当前@Styles仅支持通用属性。

@Styles可以定义在组件内或组件外,在组件外定义时需在方法名前面添加function关键字,组件内定义时则不需要添加function关键字。

// Test_Styles.ets
@Styles function globalFancy () {.width(150).height(100).backgroundColor(Color.Pink)
}@Entry
@Component
struct FancyUse {@Styles componentFancy() {.width(100).height(200).backgroundColor(Color.Yellow)}build() {Column({ space: 10 }) {Text('FancyA').globalFancy().fontSize(30)Text('FancyB').globalFancy().fontSize(20)Text('FancyC').componentFancy().fontSize(30)Text('FancyD').componentFancy().fontSize(20)}}
}

@Styles还可以在StateStyles属性内部使用,在组件处于不同的状态时赋予相应的属性。

在StateStyles内可以直接调用组件外定义的@Styles方法,但需要通过this关键字调用组件内定义的@Styles方法。

// Test_Styles.ets
@Styles function globalFancy () {.width(120).height(120).backgroundColor(Color.Green)
}@Entry
@Component
struct FancyUse {@Styles componentFancy() {.width(80).height(80).backgroundColor(Color.Red)}build() {Row({ space: 10 }) {Button('Fancy').stateStyles({normal: {.width(100).height(100).backgroundColor(Color.Blue)},disabled: this.componentFancy,pressed: globalFancy})}}
}

4 -> @Extend

@Extend装饰器将新的属性方法添加到Text、Column、Button等内置组件上,通过@Extend装饰器可以快速地扩展原生组件。

// Test_Extend.ets
@Extend(Text) function fancy (fontSize: number) {.fontColor(Color.Red).fontSize(fontSize).fontStyle(FontStyle.Italic).fontWeight(600)
}@Entry
@Component
struct FancyUse {build() {Row({ space: 10 }) {Text("Fancy").fancy(16)Text("Fancy").fancy(24)Text("Fancy").fancy(32)}}
}

说明

  • @Extend装饰器不能定义在自定义组件struct内。
  • @Extend装饰器内仅支持属性方法设置。

5 -> @CustomDialog

@CustomDialog装饰器用于装饰自定义弹窗组件,使得弹窗可以动态设置内容及样式。

// Test_CustomDialog.ets
@CustomDialog
struct DialogExample {controller: CustomDialogControlleraction: () => voidbuild() {Row() {Button('Close CustomDialog').onClick(() => {this.controller.close()this.action()})}.padding(20)}
}@Entry
@Component
struct CustomDialogUser {dialogController: CustomDialogController = new CustomDialogController({builder: DialogExample({ action: this.onAccept }),cancel: this.existApp,autoCancel: true});onAccept() {console.info('onAccept');}existApp() {console.info('Cancel dialog!');}build() {Column() {Button('Click to open Dialog').onClick(() => {this.dialogController.open()})}}
}


感谢各位大佬支持!!!

互三啦!!!


http://www.ppmy.cn/embedded/149740.html

相关文章

网络技术-QoS技术在网络中的位置

QoS技术包括流分类、流量监管、流量整形、限速、拥塞管理、拥塞避免等。下面对常用的技术进行简单地介绍。 如图,常用QoS技术在网络中的位置 如上图所示,流分类、流量监管、流量整形、拥塞管理和拥塞避免主要完成如下功能: 流分类&#xf…

Configfs - 用户空间驱动的内核对象配置

什么是configfs configfs 是一个基于 RAM 的文件系统,提供与 sysfs 相反的功能。sysfs 是一个基于文件系统的内核对象视图,而 configfs 是一个基于文件系统的内核对象管理器,即 config_items。 使用 sysfs,可以在内核中创建一个…

使用 VSCode 学习与实践 LaTeX:从插件安装到排版技巧

文章目录 背景介绍编辑器编译文件指定输出文件夹 usepackagelatex 语法列表插入图片添加参考文献 背景介绍 最近在写文章,更喜欢latex的论文引用。然后开始学习 latex。 编辑器 本文选择vscode作为编辑器,当然大家也可以尝试overleaf。 overleaf 有网…

SPI实验 LED数码管

LED数码管(LED Segment Displays)是由8个发光二极管构成,并按照一定的图形及排列封装在一起的显示器件。其中7个LED构成7笔字形,1个LED构成小数点(固有时成为八段数码管)。 LED数码管有两大类,…

【国产NI替代】基于全国产FPGA的16振动+2转速+8路IO口输入输出(24bits)256k采样率,高精度终端采集板卡

16振动2转速8路IO口输入输出(24bits) 高精度终端采集板卡 采用AG16KF256国产FPGA的硬件架构,外扩 16MB的SDRAM做为千兆网的发送缓存,比起同 款带ARM的硬件架构,纯FPGA的架构虽然边缘 计算能力不如ARM,但…

rust教程 第一章 —— 初识rust

文章目录 一、前言二、Rust简介三、安装Rust编译器四、第一个Rust程序五、 IDE环境六、初识包管理七、总结 本系列文章已升级、转移至我的自建站点中,本章原文为:初识rust 一、前言 近些年来不断有新的语言崛起,比如当下非常火的go语言&am…

1.Occ-基础部分

Occ-几何建模,几何算法,图形渲染,应用框架集大成者 1.基础类型 The primitive types are predefined in the language and they are manipulated by value. Standard_Boolean is used to represent logical data. It may have only two va…

面试场景题系列:设计支付系统

从网约车、旅游、外卖到电商或者医疗保健,幕后运行的支付系统让所有的经济活动变成可能。近年来,设计一个可靠、可扩展、灵活的支付系统成为流行的系统设计面试题。 什么是支付系统?维基百科上是这么说的,“支付系统是通过转移货…