首页 > 其他分享 >OpenHarmony应用开发之自定义弹窗

OpenHarmony应用开发之自定义弹窗

时间:2023-09-06 10:26:05浏览次数:45  
标签:OpenHarmony 自定义 100% CustomDialogController 开发 组件 弹窗

 本文转载自《OpenHarmony应用开发之自定义弹窗》,作者:zhushangyuan_

应用场景

在应用的使用和开发中,弹窗是一个很常见的场景,自定义弹窗又因为极高的自由度得以广泛应用。本文以橘子购物中一个应用更新提示的弹窗介绍OpenHarmony的自定义弹窗。

 

接口

自定义弹窗官方文档:自定义弹窗-弹窗-全局UI方法-组件参考(基于ArkTS的声明式开发范式)-ArkTS API参考-HarmonyOS应用开发

CustomDialogController是自定义弹窗对应的接口,详细介绍如下:

 

CustomDialogController(value:{builder: CustomDialog, cancel?: () => void, autoCancel?: boolean, alignment?: DialogAlignment, 
                      offset?: Offset, customStyle?: boolean, gridCount?: number, maskColor?: ResourceColor, 
                      openAnimation?: AnimateParam, closeAnimation?: AnimateParam})

 

  

参数:

 

参数名

参数类型

必填

参数描述

builder

CustomDialog

自定义弹窗内容构造器。

cancel

() => void

点击遮障层退出时的回调。

autoCancel

boolean

是否允许点击遮障层退出。默认值:true

alignment

DialogAlignment

弹窗在竖直方向上的对齐方式。默认值:DialogAlignment.Default

offset

Offset

弹窗相对alignment所在位置的偏移量。

customStyle

boolean

弹窗容器样式是否自定义。默认值:false,弹窗容器的宽度根据栅格系统自适应,

不跟随子节点;高度自适应子节点,最大为窗口高度的90%;圆角为24vp。

gridCount8+

number

弹窗宽度占栅格宽度的个数。默认为按照窗口大小自适应,异常值按默认值处理,

最大栅格数为系统最大栅格数。

这其中最重要的就是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参考文档:自定义组件的生命周期-组件参考(基于ArkTS的声明式开发范式)-ArkTS API参考-HarmonyOS应用开发

实现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应用开发

标签:OpenHarmony,自定义,100%,CustomDialogController,开发,组件,弹窗
From: https://www.cnblogs.com/openharmony/p/17681557.html

相关文章

  • DevExpress框架PropertyGridControl自定义属性,弹出框随意定制逻辑,自动设置属性到Model
    DevExpress框架WPFPropertyGridControl组件自定义属性弹出框,支持同类型属性多次设置,一次编写多次复用XAML代码<dxprg:PropertyGridControlName="property"><dxprg:PropertyDefinitionType="models:CustModel"><dxprg:PropertyDefinit......
  • OpenHarmony南向开发培训第三次作业
    Linux命令创建文件(touch)创建文件:toucha.txt创建多个文件: toucha.txtb.txt创建目录(mkdir)创建文件夹:mkdirm创建多级文件夹:mkdir-pm/n删除文件(rm)删除文件:rma.txt删除文件夹 :rm-rm删除都可用:rm-rxxx拷贝(cp)将文件拷贝到文件夹:cpa.txtc将文件夹拷贝到文......
  • uniapp项目实践总结(十)自定义滑动触摸组件
    在APP的日常开放过程中,我们经常可以看到上拉刷新、下拉刷新、左滑、右滑、触底加载等效果,那其中的原理是如何呢,又是如何实现的呢,下面就一探究竟。这篇文章主要是讲述自定义滑动触摸组件的方放,兼容网页H5端、微信小程序端和App端。目录准备工作原理分析组件实现实战......
  • OpenHarmony Framework层开发笔记
    OH源码版本:OpenHarmony-v3.2-Beta52023.04.04由于需要裁剪系统APP,原本想法是在/applications/standard/hap/BUILD.gn增加一个part的但是最后发现vendor下有现成的裁剪APP的json配置文件,所以使用gitreset还原了/applications/standard/hap/仓库下的修改导致此仓库下的所有hap......
  • 自定义企业培训系统:源码定制与扩展指南
    在现代企业中,持续学习和培训已经成为成功的关键要素之一。企业培训系统的存在已经变得不可或缺,因为它们允许企业为员工提供高质量的培训和教育,以提高他们的技能水平并满足不断变化的业务需求。然而,通用的培训系统可能无法满足每个企业的特定需求,这就是为什么自定义企业培训系统变得......
  • WPF学习 - 自定义窗体(二)
    上一篇文章写了如何创建自定义窗体:使用WindowChrome或者WindowStyle=“None”这两种方式。本文将讲述如何设置窗体的效果(以阴影效果为例),以及在效果模式下,窗体各功能的配合。一、窗体的空间范围:窗体的范围,就是白色区域部分:包括窗体的边框,标题栏,以及内部的空白部分。出了白色......
  • 自定义数据类型UI绑定
    场景:在收货地址列表页面A中,点击一个地址进详情页面B,然后修改地址保存关闭页面B,收货地址A需要同步UI更新修改的信息。机制:1、在SwiftUI中,使用@Binding只能绑定基本数据类型,不能处理自定义数据类型。2、@StateObject和@ObservedObject的监听,在目前的测试中体现的是向下传递。即......
  • #2023盲盒+码# OpenHarmony3.2壁纸设置应用整合包和安装教程
    【本文正在参加2023「盲盒」+码有奖征文活动】https://ost.51cto.com/posts/25284(目录)序言前段时间研究了下OpenHarmony3.2自带的启动器应用源码,发现壁纸设置api设置无效的根本原因在于启动器内代码写死了一个固定的图片作为壁纸,经过不断地探索尝试,最终通过修改系统启动器和......
  • a标签下载文件并自定义文件名
     一、href的属性地址必须是和你前端同源情况下<ahref="URL"download="文件名">//download属性也可以设置一个值来规定下载文件的名称。所允许的值没有限制,浏览器将自动检测正确的文件扩展名并添加到文件。注意:只有Firefox和Chrome支持download属性,如果涉及跨域情况下,d......
  • Dynamics 365 Marketing自定义渠道的步骤
    1.创建2个实体:渠道【new_flashinfosmschannel】、消息模板(配置窗体)注意:如果想用标准消息模板,可以不用创建消息模板标准消息模板效果:   2.导出解决方案,往XML增加一个关系【EntityRelationship】https://learn.microsoft.com/zh-cn/dynamics365/marketing/real-time-mark......