鸿蒙项目实战(三):自定义弹窗开发实践

news/2024/11/13 11:41:45/文章来源:https://www.cnblogs.com/xqxacm/p/18535258

自定义弹窗选型

合理选择不同的系统能力实现弹窗,有利于提升应用开发效率,实现更好的功能需求,因此了解自定义弹窗的选型和差异非常重要。在应用开发中,为了选择出合适的弹窗选型,从使用场景上,需要重点关注以下两点:

  • 弹窗与界面代码解耦

    在开发业务逻辑时,例如遇到一些网络请求失败的场景,需要触发相应的弹窗提醒用户进行操作,由于在任何页面都有可能触发对应的弹窗,此时弹窗不是与某个页面相关联,这个情况下,就需要弹窗与界面的解耦。

  • 弹窗在界面跳转后保留

    在一些权限配置页,用户首次进入应用时会弹出权限配置弹窗,让用户进行操作,此时若点击跳转到隐私详情页面,返回后弹窗需要保留在页面上。

系统提供了四种不同的方式来实现自定义弹窗,分别是CustomDialog、promptAction、UIContext.getPromptAction、Navigation.Dialog,在开发业务时,需要结合每种弹窗的特点来选择弹窗。

  • CustomDialog弹窗,必须在@Component struct内部定义,即在UI层创建控制器,当一个页面需要弹出多个自定义弹窗时,就需要创建对应个数的CustomDialogController,这会造成UI层代码冗余,无法做到弹窗与界面的解耦。
  • promptAction弹窗,为了解决CustomDialog弹窗的问题,支持了UI元素复用机制@Builder,但依赖UI组件
  • UIContext.getPromptAction弹窗,基于promptAction弹窗演进而来,支持全局自定义弹窗,不依赖UI组件,依赖UIContext,支持在非页面文件中使用,弹窗内容支持动态修改,支持自定义弹窗圆角半径、大小和位置,适合在与页面解耦的全局弹窗、自定义弹窗显示和退出动画等场景下使用。
  • Navigation.Dialog弹窗,基于Navigation路由形式,以Component组件页面存在于路由栈中,以进出栈的方式打开或关闭弹窗,可以实现弹窗与UI界面解耦,默认透明显示,适合在切换页面弹窗不消失场景下使用。

总结如下:

使用示例如下:

一、CustomerDialog

1、定义:

// 自定义提示弹框
// @CustomerDialog
@CustomDialog
export struct TipDialog {@State title: string = "提示" // 标题@State message: string = ""; // 提示内容@State cancelValue: string = "取消"; //取消按钮文案@State confirmValue: string = "确定"; //确定按钮文案cancel?: () => void // 取消事件confirm?: () => void // 确定事件controller: CustomDialogController = new CustomDialogController({builder: TipDialog()})build() {Column() {Text(this.title).width('100%').height(40).textAlign(TextAlign.Center).fontColor(Color.White).backgroundColor($r('app.color.dialog_title_bg')).borderRadius({ topLeft: 10, topRight: 10 })Text(this.message).height(70).width('100%').textAlign(TextAlign.Center).backgroundColor(Color.White)Row() {Text(this.cancelValue).layoutWeight(1).backgroundColor(Color.White).fontColor(Color.Black).textAlign(TextAlign.Center).height(40).borderRadius({ bottomLeft: 10 }).onClick(() => {if (this.cancel) {this.cancel()}})Text(this.confirmValue).layoutWeight(1).backgroundColor($r('app.color.main_color')).fontColor(Color.White).textAlign(TextAlign.Center).height(40).borderRadius({ bottomRight: 10 }).onClick(() => {if (this.confirm) {this.confirm()}})}}.width('100%')}
}

 

2、使用

import {TipDialog} from '../../components/dialogs/TipDialog'@Entry
@Component
struct More {// 有多少个弹框,就需要定义多少个CustomDialogController// 造成UI层代码冗余,无法做到弹窗与界面的解耦。controller:CustomDialogController= new CustomDialogController({builder : TipDialog({message: '点击了内容',confirm: ()=>{console.log('点击了确定')this.controller.close()},cancel: ()=>{console.log('点击了取消')this.controller.close()}}),alignment: DialogAlignment.Center,offset: { dx: 0, dy: -20 },customStyle: false,width:'80%',cornerRadius:10,backgroundColor: 0xd9ffffff,})showDialog(){this.controller.open()}build() {Row() {Column() {Button('打开弹框').fontWeight(FontWeight.Bold).onClick(()=>{this.showDialog()})}.width('100%')}.height('100%')}
}

 

二、UIContext.getPromptAction弹窗

1、定义

// 自定义弹框组件
// 使用UIContext.getPromptAction.openCustomDialog的方式
// https://developer.huawei.com/consumer/cn/doc/best-practices-V5/bpta-custome-dialog-development-practice-V5#section7466312192919
// https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-arkui-uicontext-V5#opencustomdialog12// 弹框可设置参数
export class DialogParms{public title: string = "提示" // 标题public message: string = "" // 提示内容public cancelValue: string = "取消" // 取消按钮文案public confirmValue: string = "确定" // 确定按钮文案public cancel?: (() => void) | undefined   // 取消事件public confirm?: (() => void) | undefined   // 确定事件public setTitle(value: string):void {this.title = value}public setMessage(value: string):void {this.message = value}public setCancelValue(value: string):void {this.cancelValue = value}public setConfirmValue(value: string):void {this.confirmValue = value}public setCancel(value: (() => void) | undefined){this.cancel = value}public setConfirm(value: (() => void) | undefined) {this.confirm = value}constructor(title:string) {this.title = title}}// 全局自定义函数
@Builder
export function  WarmDialog(parms:DialogParms){Column() {Text(parms.title).width('100%').height(40).textAlign(TextAlign.Center).fontColor(Color.White).backgroundColor($r('app.color.dialog_title_bg')).borderRadius({topLeft:10,topRight:10})Text(parms.message).height(70).width('100%').textAlign(TextAlign.Center).backgroundColor(Color.White)Row() {Text(parms.cancelValue).layoutWeight(1).backgroundColor(Color.White).fontColor(Color.Black).textAlign(TextAlign.Center).height(40).borderRadius({bottomLeft:10}).onClick(()=>{if (parms.cancel) {parms.cancel()}})Text(parms.confirmValue).layoutWeight(1).backgroundColor($r('app.color.main_color')).fontColor(Color.White).textAlign(TextAlign.Center).height(40).borderRadius({bottomRight:10}).onClick(()=>{if (parms.confirm) {parms.confirm()}})}}.width('80%')
}

 

2、使用

import { ComponentContent, PromptAction, UIContext } from '@kit.ArkUI';
import {WarmDialog,DialogParms} from '../../components/dialogs/WarmDialog'
@Entry
@Component
struct More {uiContext:UIContext = this.getUIContext()showDialog(){let promptAction:PromptAction = this.uiContext.getPromptAction()let dialogParms = new DialogParms("警告")dialogParms.setTitle("警告")dialogParms.setMessage("这是警告内容")dialogParms.setCancel(()=>{promptAction.closeCustomDialog(builderView)console.log('点击了取消')})dialogParms.setConfirm(()=>{promptAction.closeCustomDialog(builderView)console.log('点击了确定')})let builderView = new ComponentContent(this.uiContext,wrapBuilder(WarmDialog),dialogParms)promptAction.openCustomDialog(builderView,{alignment:DialogAlignment.Center},)}build() {Row() {Column() {Button('打开弹框').fontWeight(FontWeight.Bold).onClick(()=>{this.showDialog()})}.width('100%')}.height('100%')}
}

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/829147.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

换根 DP

树形 DP 中的换根 DP 问题又被称为二次扫描,通常需要求以每个点为根时某个式子的答案。 这一类问题通常需要遍历两次树,第一次遍历先求出以某个点(如 \(1\))为根时的答案,在第二次遍历时考虑由根为 \(u\) 转化为根为 \(v\) 时答案的变化(换根)。这个变化往往分为两部分,…

学习笔记(三十):ArkUi-UIContext.getPromptAction(弹窗)

概述: 基于promptAction弹窗演进而来,支持全局自定义弹窗,不依赖UI组件,依赖UIContext, 支持在非页面文件中使用,弹窗内容支持动态修改,支持自定义弹窗圆角半径、大小和位置, 适合在与页面解耦的全局弹窗、自定义弹窗显示和退出动画等场景下使用。 注意: 需先使用UICo…

MudBlazor:基于Material Design风格开源且强大的Blazor组件库

项目介绍 MudBlazor是一个基于Material Design风格开源、免费(MIT License)、功能强大的Blazor组件框架,注重易用性和清晰的结构。它非常适合想要快速构建Web应用程序的 .NET 开发人员,无需费力地处理 CSS 和 JavaScript。由于MudBlazor完全使用C#编写,因此你可以自由地调…

读数据工程之道:设计和构建健壮的数据系统32序列化和云网络

序列化和云网络1. 序列化 1.1. 仅仅通过从CSV转换到Parquet序列化,任务性能就提高了上百倍 1.2. 基于行的序列化1.2.1. 基于行的序列化是按行来组织数据1.2.2. 对于那些半结构化的数据(支持嵌套和模式变化的数据对象)​,基于行的序列化需要将每个对象作为一个单元来存储1.2…

入门龙芯旧世界汇编指令

我是龙芯汇编指令新手,本文是我学习龙芯汇编的笔记我借到了一台宝贵的龙芯 3A6000 设备,我期望在这台设备上面学习龙芯汇编指令。这台设备上的是龙芯旧世界的麒麟系统,由于这台设备很宝贵,我不能随意玩。为了防止弄坏设备,我将在此设备上面搭建 docker 环境,进入到 docke…

促进通用跨域检索中广义知识的模拟

促进通用跨域检索中广义知识的模拟ProS:促进通用跨域检索中广义知识的模拟通用跨域检索(UCDR)的目标是在广义测试场景中实现稳健的性能,其中数据在训练过程中可能属于严格未知的域和类别。最近,具有快速调整的预训练模型显示出很强的泛化能力,并在各种下游任务中取得了显著…

ParamISP:使用相机参数学习正向和反向ISP

ParamISP:使用相机参数学习正向和反向ISPRAW图像很少被共享,主要是因为与相机ISP获得的sRGB图像相比,RAW图像的数据量过大。最近已经证明,学习相机ISP的正向和反向过程,可以对输入的sRGB图像进行具有物理意义的RAW级图像处理。然而,现有的基于学习的ISP方法,无法处理ISP…

thinkphp console 命令行打印错误调用堆栈

在think\Console源文件里找到 run() 方法,加上内容: $output->error($e->getTraceAsString()); 然后当执行命令报错的时候就会有详细的错误信息,方便排查具体是哪行引起的问题!本文来自博客园,作者:imzhi,转载请注明原文链接:https://www.cnblogs.com/imzhi/p/18…

信道的极限容量

我们可以简单地将带通信道理解为无线传输信道,低通信道理解为有线传输信道,记忆公式时应该记住乘2的那个调制速度就是波特率

JD 商品詳情頁解析

https://item.jd.com/100036218692.html 以这个商品链接为例,分析详情图接口抓包拿到接口入参出参构建代码headers = {cookie:"",accept: application/json, text/javascript, */*; q=0.01,accept-language: zh-CN,zh;q=0.9,origin: https://item.jd.com,priority: …

Vmware虚拟机下载安装使用教程(17.5.2最新版非常详细)

VMware,自1998年成立以来,便以其革命性的虚拟化技术引领行业。这家公司专注于提供软件和服务,支持云计算和虚拟化解决方案,使得一台物理服务器能够托管多个独立的虚拟机,每个虚拟机都能独立运行不同的操作系统和应用。VMware的技术不仅优化了硬件资源的使用效率,还简化了…