OpenHarmony应用开发之自定义弹窗
应用场景
在应用的使用和开发中,弹窗是一个很常见的场景,自定义弹窗又因为极高的自由度得以广泛应用。本文以橘子购物中一个应用更新提示的弹窗介绍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.Default |
|
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
层叠布局(Stack)-构建布局-开发布局-基于ArkTS的声明式开发范式-UI开发-开发-HarmonyOS应用开发
线性布局(Row/Column)-构建布局-开发布局-基于ArkTS的声明式开发范式-UI开发-开发-HarmonyOS应用开发
按钮(Button)-添加常用组件-添加组件-基于ArkTS的声明式开发范式-UI开发-开发-HarmonyOS应用开发
OpenHarmony应用开发之自定义弹窗的更多相关文章
- 微信小程序自定义弹窗wcPop插件|仿微信弹窗样式
微信小程序自定义组件弹窗wcPop|小程序消息提示框|toast自定义模板弹窗 平时在开发小程序的时候,弹窗应用场景还是蛮广泛的,但是微信官方提供的弹窗比较有局限性,不能自定义修改.这个时候首先想到的 ...
- svelte组件:Svelte自定义弹窗Popup组件|svelte移动端弹框组件
基于Svelte3.x自定义多功能svPopup弹出框组件(组件式+函数式) 前几天有分享一个svelte自定义tabbar+navbar组件,今天继续带来svelte自定义弹窗组件. svPopup ...
- ExtJs基础知识总结:自定义弹窗和ComboBox自动联想加载(四)
概述 Extjs弹窗可以分为消息弹窗.对话框,这些弹窗的方式ExtJs自带的Ext.Msg.alert就已经可以满足简单消息提示,但是相对复杂的提示,比如如何将Ext.grid.Panel的控件显示嵌 ...
- iOS开发之自定义表情键盘(组件封装与自动布局)
下面的东西是编写自定义的表情键盘,话不多说,开门见山吧!下面主要用到的知识有MVC, iOS开发中的自动布局,自定义组件的封装与使用,Block回调,CoreData的使用.有的小伙伴可能会问写一个自 ...
- xamarin UWP平台下 HUD 自定义弹窗
在我的上一篇博客中我写了一个在xamarin的UWP平台下的自定义弹窗控件.在上篇文章中介绍了一种弹窗的写法,但在实际应用中发现了该方法的不足: 1.当弹窗出现后,我们拖动整个窗口大小的时候,弹窗的窗 ...
- android开发之自定义组件
android开发之自定义组件 一:自定义组件: 我认为,自定义组件就是android给我们提供的的一个空白的可以编辑的图片,它帮助我们实现的我们想要的界面,也就是通过自定义组件我们可以把我们要登入的 ...
- 手机3D游戏开发:自定义Joystick的相关设置和脚本源码
Joystick在手游开发中非常常见,也就是在手机屏幕上的虚拟操纵杆,但是Unity3D自带的Joystick贴图比较原始,所以经常有使用自定义贴图的需求. 下面就来演示一下如何实现自定义JoySti ...
- PHPCMS V9二次开发便捷自定义后台入口文件夹
phpcms v9二次开发便捷自定义后台入口文件夹 最新发布的phpcms v9由于采用了mvc的设计模式,所以它的后台访问地址是固定的,虽然可以通过修改路由配置文件来实现修改,但每次都修改路由配置文 ...
- 详解iOS开发之自定义View
iOS开发之自定义View是本文要将介绍的内容,iOS SDK中的View是UIView,我们可以很方便的自定义一个View.创建一个 Window-based Application程序,在其中添加 ...
- 如何开发使用自定义文件的OEM应用程序
有关创建和使用自定义数据文件的详细信息,请参阅DISM应用程序包(.appx或.appxbundle)服务命令行选项. 了解如何开发使用自定义文件的应用程序,将信息从OEM传递到应用程序. 对于您为O ...
随机推荐
- 案例分享:Qt便携式致病菌快速检测仪(账号管理、实验过程、二维图表、历史数据、通讯管理、实验报告、中英文等等)
需求 根据提供的用户原型设计.ui设计.通讯协议研发便携式致病菌快速检测仪器软件. 100%还原ui. 基本主功能(推荐visio:★★★☆☆,前期主流程需求整理) Dem ...
- 【webserver 前置知识 02】Linux网络编程入门其一
网络结构模式 C/S结构 服务器 - 客户机,即 Client - Server(C/S)结构.C/S 结构通常采取两层结构.服务器负责数据的管理,客户机负责完成与用户的交互任务.客户机是因特网上访问 ...
- 第119篇: JavaScript 类
好家伙,我们先来复习一下 关于Java,类的三大特征: 1.封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏. 2.继承,继承性更 ...
- Html飞机大战(十五): 上线
好家伙, 我的飞机大战部署上线了 胖虎的飞机大战 感兴趣的可以去玩一下 (怕有人接受不了这个背景,我还贴心的准备切换背景按钮,然而这并没有什么用) 现在,我们停下脚步,重新审视这个游戏 ...
- 面试必备:一线大厂Redis缓存设计规范与性能优化
说在前面 你是否在使用Redis时,不清楚Redis应该遵循的设计规范而苦恼? 你是否在Redis出现性能问题时,不知道该如何优化而发愁? 你是否被面试官拷问过Redis的设计规范和性能优化而回答不出 ...
- ASP.NET Core 选项
目录 1,选项接口 2,注入配置与IOptions 3,IOptionsSnapshot 首先要了解 ASP.NET Core 中的配置,请点击这里了解:https://www.cnblogs.com ...
- 图数据库 Nebula Graph 的代码变更测试覆盖率实践
对于一个持续开发的大型工程而言,足够的测试是保证软件行为符合预期的有效手段,而不是仅仅依靠 code review 或者开发者自己的技术素质.测试的编写理想情况下应该完全定义软件的行为,但是通常情况都 ...
- Java 类的内部成员之五:内部类
1 package com.bytezreo.innerclass; 2 3 /** 4 * 5 * @Description 类的内部成员之五:内部类 6 * @author Bytezero·zh ...
- 数据处理——IF函数求同时满足多个条件 多个条件满足一个以上
以满足两个条件为例,满足多个条件类似 以如下案例为例进行说明: 一.IF公式同时满足多个条件 此例也可使用函数的嵌套,对于函数使用掌握不牢的新手,嵌套使用会有些困难,以下方法针对刚入门学习参考 1.利 ...
- STM32进入HardFault_Handler的调试方法
在编写STM32程序代码时由于自己的粗心会发现有时候程序跑着跑着就进入了 HardFault_Handler中断,按照经验来说进入HardFault_Handler故障的原因主要有两个方面: 1:内存 ...