写点什么

OpenHarmony 应用开发之自定义弹窗

  • 2023-09-06
    北京
  • 本文字数:3341 字

    阅读完需:约 11 分钟

OpenHarmony应用开发之自定义弹窗

本文转载自《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应用开发

用户头像

OpenHarmony开发者官方账号 2021-12-15 加入

OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及运营的开源项目,目标是面向全场景、全连接、全智能时代,基于开源的方式,搭建一个智能终端设备操作系统的框架和平台,促进万物互联产业的繁荣发展

评论

发布
暂无评论
OpenHarmony应用开发之自定义弹窗_OpenHarmony_OpenHarmony开发者_InfoQ写作社区