乐趣区

关于openharmony: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 {}

弹窗上所需的数据和获取也须要在在此处定义:

@CustomDialog
export 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 利用开发

退出移动版