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 ...
随机推荐
- 【八股cover#3】计网 Q&A与知识点
计网知识点Q&A 简历cover 1.TCP/IP网络模型 网络模型 TCP/IP 协议族,它是一个分层.多协议的通信体系. TCP/IP协议族是一个四层协议系统,自底而上分别是数据链 ...
- 【LeetCode字符串#04】左旋转字符串,以及反转函数使用说明
左旋转字符串 力扣题目链接(opens new window) 字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部.请定义一个函数实现字符串左旋转操作的功能.比如,输入字符串"a ...
- Vue源码学习(十一):计算属性computed初步学习
好家伙, 1.Computed实现原理 if (opts.computed) { initComputed(vm,opts.computed); } function initComputed(v ...
- 如何将 IPhone 的文件导入 Linux
如何将 IPhone 的文件导入 Linux 完全免费方案. 方法一: 使用 Koder 的 Local File Access 功能 这方法不需要在 Linux 端做任何配置. IPhone 端 安 ...
- Java 手动抛异常
1 package com.bytezero.throwable; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 impor ...
- docker构建带ik分词器Elasticsearch镜像
创建Dockerfile 文件: FROM elasticsearch:7.4.2 RUN cd /usr/share/elasticsearch && sh -c '/bin/ech ...
- MySql注入—DNS注入
MySql注入-DNS注入 1.DNS注入原理 一.DNS注入原理 DNS注入,是通过查询相应DNS解析产生的记录日志来获取想要的数据 对于sql盲注这样的方法常常用到二分法,非常麻烦而且没有回显,要 ...
- Grails的数据库相关开发
1.开发domain和service 在出来的输入框里输入domain的名字,可以包括包名. 这里我输入test.domain.House,点finish 创建了两个groovy文件,一个当然是tes ...
- 像使用stl一样使用线段树 ——AtCoder Library(转载https://zhuanlan.zhihu.com/p/459579152)
地址:https://zhuanlan.zhihu.com/p/459579152 我这里翻译一下官方的文档. 首先需要满足几个性质. (注意 ∗ 是个操作,不是单纯的一个乘号) 1)操作满足结合律 ...
- 大年学习linux(第四节---文件权限)
四.文件权限 文件类型 Linux文件类型和linux文件的文件名所代表的意义是两个不同的概念.我们通过一般应用程序而创建的比如 file.txt.file.tar.gz ,这些文件虽然要用不同的程序 ...
