OpenHarmony——ets自定义弹窗UI组件封装

炒沙作縻终不饱,缕冰文章费工巧。这篇文章主要讲述OpenHarmony——ets自定义弹窗UI组件封装相关的知识,希望能为你提供帮助。
作者:凌小凤 前言?鸿蒙已经提供了全局UI方法自定义弹窗,本文是基于基础的自定义弹窗来实现提示消息弹窗、确认弹窗、输入弹窗的UI组件封装。
一、消息确认弹窗首先看下效果:
【OpenHarmony——ets自定义弹窗UI组件封装】

OpenHarmony——ets自定义弹窗UI组件封装

文章图片

1.1、首先先定义一个新的组件ConfirmDialog
@CustomDialog export default struct ConfirmDialog title: string = content: string = confirmFontColor: string = #E84026 cancelFontColor:string = #0A59F7 confirmText:string = 确认 cancelText:string = 取消 controller: CustomDialogController cancel: () => void confirm: () => void build()

自定义确认弹窗可自定义传入的参数有:
?可选参数:标题title(默认值:" " ),正文内容content(默认值:" " ),确认按钮字体颜色confirmFontColor(默认值:#E84026),取消按钮字体颜色cancelFontColor(默认值:#0A59F7),确认按钮文案(默认值:确认),取消按钮文案(默认值:取消)
?必须参数:自定义弹窗控制器controller: CustomDialogController,确认按钮触发事件confirm(),取消按钮触发事件cancel()
1.2、标题、正文、按钮封装一个确认弹窗组件主要由标题、正文等文本内容和取消、确认等按钮事件组成。下面将分别对文案和按钮通过@Extend装饰器进行封装。
@Extend装饰器将新的属性函数添加到内置组件上,如Text、Column、Button等。通过@Extend装饰器可以快速定义并复用组件的自定义样式。
OpenHarmony——ets自定义弹窗UI组件封装

文章图片

// 标题title与正文content自定义样式 @Extend(Text) function fancfontSize(fontSize: number) .fontSize(fontSize) .width(100%) .fontColor(rgba(0, 0, 0, 0.86)) .textAlign(TextAlign.Center) .padding( top: 15, bottom: 0, left: 8, right: 8 ) .alignSelf(ItemAlign.Center) .margin(top: 16)// 取消、确认按钮自定义样式 @Extend(Text) function fancBtn(fontColor: string) .fontColor(fontColor) .backgroundColor(0xffffff) .width(188) .height(29) .fontSize(22) .textAlign(TextAlign.Center)

本示例仅标题与正文仅支持字体大小fontSize自定义,按钮仅支持按钮文案字体颜色fontColor自定义,其他通用属性皆是写定的,若想支持其他属性自定义,也可通过fancfontSize()添加新的参数。
其次,可以更进一步的对标题与正文通过@Builder装饰器进行封装,且通过是否传入title、content字段来判断是否展示对应文案。
@Builder装饰的方法用于定义组件的声明式UI描述,在 一个自定义组件内快速生成多个布局内容。@Builder装饰方法的功能和语法规范与build函数相同。
// 文案样式 @Builder TipTextStyle(tip:string, fontSize:number) Text(tip) .fancfontSize(fontSize) .visibility(tip.length > 0 ? Visibility.Visible : Visibility.None)

注意:1、@Extend装饰器的内容必须写在ConfirmDialog组件外,且在@Extend装饰器声明的基础内置组件的方法之前不能出现用/*多行注释(会报错),但可采用单行注释//。
?2、@Builder装饰器的内容要写在ConfirmDialog组件内,build()外 。
?3、@Builder装饰器声明的自定义组件内部可包含@Extend声明的自定义样式的基础组件,但是@Extend内部不可包含@Builder装饰器声明的自定义组件。
1.3、ConfirmDialog组件完整代码
// 取消、确认按钮自定义样式 @Extend(Text) function fancBtn(fontColor: string) .fontColor(fontColor) .backgroundColor(0xffffff) .width(188) .height(29) .fontSize(22) .textAlign(TextAlign.Center)// 标题title与正文content自定义样式 @Extend(Text) function fancfontSize(fontSize: number) .fontSize(fontSize) .width(100%) .fontColor(rgba(0, 0, 0, 0.86)) .textAlign(TextAlign.Center) .padding( top: 15, bottom: 0, left: 8, right: 8 ) .alignSelf(ItemAlign.Center) .margin(top: 16)@CustomDialog export default struct ConfirmDialog title: string = content: string = confirmFontColor: string = #E84026 cancelFontColor:string = #0A59F7 confirmText:string = 确认 cancelText:string = 取消 controller: CustomDialogController cancel: () => void confirm: () => void // 标题、正文文案样式 @Builder TipTextStyle(tip:string, fontSize:number) Text(tip) .fancfontSize(fontSize) .visibility(tip.length > 0 ? Visibility.Visible : Visibility.None)build() Column() this.TipTextStyle(this.title, 28) this.TipTextStyle(this.content, 22) Flex( justifyContent: FlexAlign.SpaceAround ) Text(this.cancelText) .fancBtn(this.cancelFontColor) .onClick(() => this.controller.close() this.cancel() ) Text(this.confirmText) .fancBtn(this.confirmFontColor) .onClick(() => this.controller.close() this.confirm() ) .margin( top: 30, bottom: 16, left: 16, right: 16 )

1.4、引用页面代码
import ConfirmDialog from ./components/dialog/ConfirmDialog.ets @Entry @Component struct IndexComponent // 确认弹窗 private title: string = 标题 private content: string = 此操作将永久删除该文件, 是否继续? private confirmText: string = 删除 ConfirmDialogController: CustomDialogController = new CustomDialogController( builder: ConfirmDialog( cancel: this.onCancel, confirm: () => this.onAccept() ,title:this.title, content: this.content), cancel: this.onCancel, autoCancel: true ) // 点击取消按钮或遮罩层关闭弹窗 onCancel() console.info(取消,关闭弹窗)// 点击确认弹窗 onAccept() console.info(确认,关闭弹窗)build() Scroll() Column() Text(确认弹窗) .fontSize(24) .width(300) .height(60) .border( width: 5, color: 0x317AF7, radius: 10, style: BorderStyle.Solid ) .margin(top: 20, bottom:10) .textAlign(TextAlign.Center) .onClick(() => this.ConfirmDialogController.open() ).width(100%)

二、消息提示弹窗首先看下效果:
OpenHarmony——ets自定义弹窗UI组件封装

文章图片

2.1、首先先定义一个新的组件PromptDialog
@CustomDialog export default struct PromptDialog controller: CustomDialogController ancel: () => void build()

至于标题、正文、按钮文案及按钮颜色的封装均与消息确认弹窗一样,同1.2所述。
2.2、PromptDialog组件完整代码
// 标题title与正文content自定义样式 @Extend(Text) function fancfontSize(fontSize: number) .fontSize(fontSize) .width(100%) .fontColor(rgba(0, 0, 0, 0.86)) .textAlign(TextAlign.Center) .padding( top: 15, bottom: 0, left: 8, right: 8 ) .alignSelf(ItemAlign.Center) .margin(top: 16)// 底部按钮自定义样式 @Extend(Text) function fancBtn(fontColor: string) .backgroundColor(0xffffff) .fontColor(fontColor) .width(188) .height(29) .fontSize(22) .textAlign(TextAlign.Center)@CustomDialog export default struct PromptDialog controller: CustomDialogController cancel: () => void // 标题、正文文案样式 @Builder TipTextStyle(tip:string, fontSize:number) Text(tip) .fancfontSize(fontSize) .visibility(tip.length > 0 ? Visibility.Visible : Visibility.None)build() Column() this.TipTextStyle($s(strings.title), 28) this.TipTextStyle($s(strings.content), 22) Flex( justifyContent: FlexAlign.Center ) Text($s(strings.confirm)) .fancBtn(0x0A59F7) .onClick(() => this.controller.close() ) .margin( top: 30, bottom: 16 )

若标题title与正文content中的文案是固定的,可如此示例一样,可采用写入到resource中的zh_CN和en_US文件中,通过$s(strings.title)取值显示,若是动态获取的,可采用消息确认弹窗中传参方式。
OpenHarmony——ets自定义弹窗UI组件封装

文章图片

2.3、引用页面代码
import PromptDialog from ./components/dialog/PromptDialog.ets @Entry @Component struct IndexComponent // 消息提示弹窗 PromptDialogController: CustomDialogController = new CustomDialogController( builder: PromptDialog(), autoCancel: true )build() Scroll() Column() Text(消息提示弹窗) .fontSize(24) .width(300) .height(60) .border( width: 5, color: 0x317AF7, radius: 10, style: BorderStyle.Solid ) .margin(top: 20, bottom:10) .textAlign(TextAlign.Center) .onClick(() => this.PromptDialogController.open() ).width(100%)

三、消息输入弹窗首先看下效果:
OpenHarmony——ets自定义弹窗UI组件封装

文章图片

3.1、首先先定义一个新的组件InputDialog
export default struct InputDialog title: string = content: string = @State inputString:string = controller: CustomDialogController cancel: () => void confirm: (data) => voidbuild()

此示例讲述了子组件通过事件触发传参给父组件的方法,例如:在子组件用@state声明输入框内容inputString,通过confirm事件传参给父组件,可支持在父组件至于标题、正文、按钮文案及按钮颜色的封装均与消息确认弹窗一样,同1.2所述。
3.2、PromptDialog组件完整代码
// 取消、确认按钮自定义样式 @Extend(Text) function fancBtn(fontColor: string) .fontColor(fontColor) .backgroundColor(0xffffff) .width(188) .height(29) .fontSize(22) .textAlign(TextAlign.Center)// 标题title与正文content自定义样式 @Extend(Text) function fancfontSize(fontSize: number) .fontSize(fontSize) .width(100%) .fontColor(rgba(0, 0, 0, 0.86)) .textAlign(TextAlign.Start) .padding( top: 15, bottom: 0, left: 15, right: 15 ) .margin(top: 16)@CustomDialog export default struct InputDialog title: string = content: string = @State inputString:string = controller: CustomDialogController cancel: () => void confirm: (data) => void // 文案样式 @Builder TipTextStyle(tip:string, fontSize:number) Text(tip) .fancfontSize(fontSize) .visibility(tip.length > 0 ? Visibility.Visible : Visibility.None)build() Column() this.TipTextStyle(this.title, 28) this.TipTextStyle(this.content, 22) // 输入框 TextInput() .type(InputType.Normal) .enterKeyType(EnterKeyType.Next) .caretColor(Color.Green) .height(44) .margin(top: 20, left: 15; right:15) .alignSelf(ItemAlign.Center) .onChange((value: string) => this.inputString = value ) Flex( justifyContent: FlexAlign.SpaceAround ) Text($s(strings.cancel)) .fancBtn(#0A59F7) .onClick(() => this.controller.close() this.cancel() ) Text($s(strings.confirm)) .fancBtn(#E84026) .onClick(() => this.controller.close() console.log(inputString:+this.inputString) this.confirm(this.inputString) ) .margin( top: 30, bottom: 16, left: 16, right: 16 )

OpenHarmony——ets自定义弹窗UI组件封装

文章图片

3.3、引用页面代码
import InputDialog from ./components/dialog/InputDialog.ets @Entry @Component struct IndexComponent // 输入弹窗 private text: string = 提示 private label: string = 请输入您的姓名 InputDialogController: CustomDialogController = new CustomDialogController( builder: InputDialog( cancel: this.onCancel, confirm: (data) => this.confirm(data) ,title: this.text, content: this.label ), cancel: this.onCancel, autoCancel: true ) // 点击取消按钮或遮罩层关闭弹窗 onCancel() console.info(取消,关闭输入弹窗)// 点击确认弹窗 confirm(data) console.info(确认,关闭输入弹窗,data:+data)build() Scroll() Column() Text(输入弹窗) .fontSize(24) .width(300) .height(60) .border( width: 5, color: 0x317AF7, radius: 10, style: BorderStyle.Solid ) .margin(top: 20, bottom:10) .textAlign(TextAlign.Center) .onClick(() => this.InputDialogController.open() ).width(100%)

总结?本文仅仅实现了三种自定义弹窗UI组件的封装(传参方式也讲解了多种,具体传参方式可视具体情况而定),待笔者优化了功能、代码后在来与大家分享, 在最后欢迎鸿蒙各位大佬指教。
更多原创内容请关注:深开鸿技术团队入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。
想了解更多关于鸿蒙的内容,请访问:
51CTO和华为官方合作共建的鸿蒙技术社区
https://ost.51cto.com/#bkwz
::: hljs-center
OpenHarmony——ets自定义弹窗UI组件封装

文章图片

:::

    推荐阅读