本文转载自《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应用开发之自定义弹窗的更多相关文章

  1. 微信小程序自定义弹窗wcPop插件|仿微信弹窗样式

    微信小程序自定义组件弹窗wcPop|小程序消息提示框|toast自定义模板弹窗 平时在开发小程序的时候,弹窗应用场景还是蛮广泛的,但是微信官方提供的弹窗比较有局限性,不能自定义修改.这个时候首先想到的 ...

  2. svelte组件:Svelte自定义弹窗Popup组件|svelte移动端弹框组件

    基于Svelte3.x自定义多功能svPopup弹出框组件(组件式+函数式) 前几天有分享一个svelte自定义tabbar+navbar组件,今天继续带来svelte自定义弹窗组件. svPopup ...

  3. ExtJs基础知识总结:自定义弹窗和ComboBox自动联想加载(四)

    概述 Extjs弹窗可以分为消息弹窗.对话框,这些弹窗的方式ExtJs自带的Ext.Msg.alert就已经可以满足简单消息提示,但是相对复杂的提示,比如如何将Ext.grid.Panel的控件显示嵌 ...

  4. iOS开发之自定义表情键盘(组件封装与自动布局)

    下面的东西是编写自定义的表情键盘,话不多说,开门见山吧!下面主要用到的知识有MVC, iOS开发中的自动布局,自定义组件的封装与使用,Block回调,CoreData的使用.有的小伙伴可能会问写一个自 ...

  5. xamarin UWP平台下 HUD 自定义弹窗

    在我的上一篇博客中我写了一个在xamarin的UWP平台下的自定义弹窗控件.在上篇文章中介绍了一种弹窗的写法,但在实际应用中发现了该方法的不足: 1.当弹窗出现后,我们拖动整个窗口大小的时候,弹窗的窗 ...

  6. android开发之自定义组件

    android开发之自定义组件 一:自定义组件: 我认为,自定义组件就是android给我们提供的的一个空白的可以编辑的图片,它帮助我们实现的我们想要的界面,也就是通过自定义组件我们可以把我们要登入的 ...

  7. 手机3D游戏开发:自定义Joystick的相关设置和脚本源码

    Joystick在手游开发中非常常见,也就是在手机屏幕上的虚拟操纵杆,但是Unity3D自带的Joystick贴图比较原始,所以经常有使用自定义贴图的需求. 下面就来演示一下如何实现自定义JoySti ...

  8. PHPCMS V9二次开发便捷自定义后台入口文件夹

    phpcms v9二次开发便捷自定义后台入口文件夹 最新发布的phpcms v9由于采用了mvc的设计模式,所以它的后台访问地址是固定的,虽然可以通过修改路由配置文件来实现修改,但每次都修改路由配置文 ...

  9. 详解iOS开发之自定义View

    iOS开发之自定义View是本文要将介绍的内容,iOS SDK中的View是UIView,我们可以很方便的自定义一个View.创建一个 Window-based Application程序,在其中添加 ...

  10. 如何开发使用自定义文件的OEM应用程序

    有关创建和使用自定义数据文件的详细信息,请参阅DISM应用程序包(.appx或.appxbundle)服务命令行选项. 了解如何开发使用自定义文件的应用程序,将信息从OEM传递到应用程序. 对于您为O ...

随机推荐

  1. 硬件开发笔记(十): 硬件开发基本流程,制作一个USB转RS232的模块(九):创建CH340G/MAX232封装库sop-16并关联原理图元器件

    前言   有了原理图,可以设计硬件PCB,在设计PCB之间还有一个协同优先动作,就是映射封装,原理图库的元器件我们是自己设计的.为了更好的表述封装设计过程,本文描述了CH340G和MAX232芯片封装 ...

  2. 项目实战:Qt+OSG教育学科工具之地理三维星球

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  3. 1.Go 的基本数据类型

    Go 的基本数据类型

  4. 03、Etcd 客户端常用命令

    上一讲我们安装 etcd 服务端,这一讲我们来一起学学如何使用 etcd 客户端常见的命令.文章内容来源于参考资料,如若侵权,请联系删除,谢谢. etcd可通过客户端命令行工具 etcdctl 对et ...

  5. C++之指针变量的定义和使用

    从b站上黑马程序员的c++课里学到的C++之指针变量的定义和使用 指针变量的定义和使用 简单理解指针就是地址. 内存编号是从0开始记录的,一般用16进制数字表示 1 #include <iost ...

  6. MAUI调用.so库

    必要条件: (一)安装JDK (二)安装NDK (三)安装Android Studio(其实可以不用装也行) 使用Android Studio构件.so包 构件.so包 1. 使用Android st ...

  7. Java final 关键字使用

    1 package com.bytezreo.finaltest; 2 3 /** 4 * 5 * @Description final 关键字使用 6 * @author Bytezero·zhen ...

  8. vite 子项目 热部署 通过nginx,和父项目端口号不同,导致热更新的websocket报错的解决方案

    vite 子项目 热部署 通过nginx,和父项目端口号不同,导致热更新的websocket报错的解决方案 我的父项目端口号是8888 子项目端口号是 8013 这里报错的原因就是,热更新的webso ...

  9. ncc - koa 后台源码加密打包工具 @vercel/ncc - webpack node打包更正规

    加个重点 webpack 打包更正规 安装 npm i -g @vercel/ncc 又发现一个 https://github.com/zeit/ncc npm i -g @zeit/ncc 卸载之前 ...

  10. Vue3 好文收藏

    实用!最新的几个 Vue 3 重要特性提案 http://www.zyiz.net/tech/detail-142574.html