本文转载自《OpenHarmony 利用开发之自定义弹窗》,作者:zhushangyuan_
利用场景
在利用的应用和开发中,弹窗是一个很常见的场景,自定义弹窗又因为极高的自由度得以广泛应用。本文以橘子购物中一个利用更新提醒的弹窗介绍 OpenHarmony 的自定义弹窗。
接口
自定义弹窗官网文档:https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/ts-methods-custom-dialog-box-0000001477981237-V3#ZH-CN_TOPIC_0000001574128801__customdialogcontroller
CustomDialogController 是自定义弹窗对应的接口,具体介绍如下:
CustomDialogController(value:{builder: CustomDialog, cancel?: () => void, autoCancel?: boolean, alignment?: DialogAlignment, offset?: Offset, customStyle?: boolean, gridCount?: number, maskColor?: ResourceColor, openAnimation?: AnimateParam, closeAnimation?: AnimateParam})
参数:
这其中最重要的就是 builder,咱们须要本人实现一个结构器,也就是这个弹窗的页面。
具体实现
定义 CustomDialogController
首先,咱们须要定义一个 CustomDialogController:
UpdateDialogController: CustomDialogController = new CustomDialogController({ builder: UpdateDialog(), customStyle: true})
这个 CustomDialogController 就代表弹窗,UpdateDialog()是弹窗的具体实现,customStyle 为 ture 就示意弹窗款式能够自定义。
设置调用机会
在这个场景中,咱们想要每次关上利用的时候弹窗,其余时候不弹窗,咱们须要在首页组件的 aboutToAppear 中退出以下代码:
aboutToAppear() { if(AppStorage.Get('nowIndex') === undefined || AppStorage.Get('nowIndex') === 0){ this.UpdateDialogController.open() }}
aboutToAppear 函数的调用机会是创立自定义组件的新实例后,执行其 build()函数之前,所以在首页组件的 aboutToAppear 退出 CustomDialogController 的关上开逻辑可使弹窗仅在利用关上的时候触发。
aboutToAppear 参考文档:https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/arkts-custom-component-lifecycle-0000001482395076-V3#ZH-CN_TOPIC_0000001523488850__abouttoappear
实现 builder 实例
实现实例能够间接在 builder 前面间接实现,也能够定义在其余文件中,而后通过调用的形式获取,本文以调用形式实现。
实例组件的定义前需加 export 能力裸露进来:
export struct UpdateDialog {}
弹窗上所需的数据和获取也须要在在此处定义:
@CustomDialogexport struct UpdateDialog { @State currentVersion: string = '' @State richTextData: string = '' @State lastVersion: string = '' @State updateContent: string = '' private context?: AbilityContext private customDialogController?: CustomDialogController async aboutToAppear() { this.context = getContext(this) as AbilityContext this.richTextData = await dialogFeature.getRichTextData(this.context) Logger.info(TAG, `this.richTextData = ${this.richTextData}`) await this.getData() } async getData() { try { this.currentVersion = await dialogFeature.getCurrentVersion() let requestResponseContent: RequestResponseContent = await dialogFeature.getLastVersion() if (requestResponseContent.content === null || requestResponseContent.content === undefined) { return } this.updateContent = requestResponseContent.content if (requestResponseContent.versionName === null || requestResponseContent.versionName === undefined) { return } this.lastVersion = requestResponseContent.versionName } catch (err) { Logger.info(TAG, `getApplicationVersion is fail`) } } ...
以上是利用降级所需的数据结构及局部数据获取。
弹窗具体实现
自定义弹窗的实现就是在原页面的根底上再加一层页面,页面内容自定义。
弹窗页面咱们能够通过 stack 组件实现,stack 组件会使容器内的子组件重叠布局,应用 stack 的益处是能够增加一层遮罩成果。
Stack() { // mask 遮罩层 Column() .width('100%') .height('100%') .backgroundColor('#000000') .opacity(.4) ...
以上代码在 stack 的第一层设置了 backgroundColor 和 opacity 属性,这样会产生如开始示意图的遮罩成果。
须要留神的是,须要在勾销按钮的调用函数中敞开弹窗,具体代码如下:
Button($r('app.string.cancel')) .onClick(() => { this.customDialogController.close() })
弹窗残缺代码:
build() { Stack() { // mask 遮罩层 Column() .width('100%') .height('100%') .backgroundColor('#000000') .opacity(.4) Column() { Stack({ alignContent: Alignment.TopStart }) { Text($r('app.string.update_title')) .fontSize(30) .fontColor('#FFFFFF') .fontWeight(500) .margin({ top: 70, left: 76 }) Text(`V${(this.lastVersion || updateData.versionName)}`) .fontSize(16) .backgroundColor('#FFFFFF') .textAlign(TextAlign.Center) .fontColor('#E9304E') .borderRadius(20) .width(80) .aspectRatio(2.8) .margin({ top: 110, left: 76 }) Column() { // 富文本容器 Scroll() { Column() { if (this.richTextData) { RichText((this.updateContent || this.richTextData)) .width('100%') .height('100%') } } .width('100%') } .height(200) Row() { Button($r('app.string.cancel')) .commonButtonStyle() .fontSize(20) .margin({ left: 10 }) .fontColor('#E92F4F') .backgroundColor('rgba(0,0,0,0.05)') .margin({ right: 10 }) .onClick(() => { this.customDialogController.close() }) .key("cancel") Button($r('app.string.update_now')) .commonButtonStyle() .fontSize(20) .margin({ right: 10 }) .fontColor('#FFFFFF') .backgroundColor('#E92F4F') .margin({ left: 10 }) .onClick(() => { this.customDialogController.close() }) .key("Now") } .margin({ top: 30 }) } .width('100%') .padding({ left: 25, right: 25 }) .margin({ top: 230 }) } .height(600) .width('100%') .backgroundImage($r('app.media.update'), ImageRepeat.NoRepeat) .backgroundImageSize(ImageSize.Contain) } .width(480) .padding({ left: 16, right: 16 }) } .width('100%') .height('100%')}
以上是弹窗残缺代码,须要留神的是,本例并未实现利用降级的具体逻辑,所以降级按钮的操作也是敞开弹窗。
参考
本文供稿:https://gitee.com/JaysonLiu3
本例参考的官网文档:橘子购物
自定义弹窗官网文档
自定义组件的生命周期-aboutToAppear
层叠布局(Stack)-构建布局-开发布局-基于ArkTS的申明式开发范式-UI开发-开发-HarmonyOS利用开发
线性布局(Row/Column)-构建布局-开发布局-基于ArkTS的申明式开发范式-UI开发-开发-HarmonyOS利用开发
按钮(Button)-增加罕用组件-增加组件-基于ArkTS的申明式开发范式-UI开发-开发-HarmonyOS利用开发