当前位置: 首页 > article >正文

HarmonyOS Next中的弹出框使用

HarmonyOS Next弹出框概述及分类

弹出框是一种模态窗口,通常用于在保持当前上下文环境的同时,临时展示用户需关注的信息或待处理的操作。用户需在模态弹出框内完成相关交互任务之后,才能退出模态模式。弹出框可以不与任何组件绑定,其内容通常由多种组件组成,如文本、列表、输入框、图片等,以实现布局。ArkUI当前提供了自定义固定样式两类弹出框组件。

  • 自定义弹出框: 开发者需要根据使用场景,传入自定义组件填充在弹出框中实现自定义的弹出框内容。主要包括基础自定义弹出框 (CustomDialog)、不依赖UI组件的自定义弹出框 (openCustomDialog)。
  • 固定样式弹出框: 开发者可使用固定样式弹出框,指定需要显示的文本内容和按钮操作,完成简单的交互效果。主要包括警告弹窗 (AlertDialog)、列表选择弹窗 (ActionSheet)、选择器弹窗 (PickerDialog)、对话框 (showDialog)、操作菜单 (showActionMenu)。

本文主要是介绍自定义弹出框的使用,固定样式弹出框可以参考官方文档,自定义弹出框主要有两种实现方式:

1、基础自定义弹出框 (CustomDialog)(不推荐)

2、不依赖UI组件的全局自定义弹出框 (openCustomDialog)(推荐)

基础自定义弹出框 (CustomDialog)

CustomDialog是自定义弹出框,可用于广告、中奖、警告、软件更新等与用户交互响应操作。通过CustomDialogController类显示自定义弹窗。使用弹窗组件时,可优先考虑自定义弹窗,便于自定义弹窗的样式与内容。

1、@CustomDialog装饰器

使用@CustomDialog装饰器装饰自定义弹出框,可在此装饰器内自定义弹出框内容。这里在装饰器内添加确定和取消按钮,也可以同时添加数据函数。

@CustomDialog
struct CustomDialogExample {
  cancel?: () => void
  confirm?: () => void
  controller: CustomDialogController

  build() {
    Column() {
      Text('我是内容').fontSize(20).margin({ top: 10, bottom: 10 })
      Flex({ justifyContent: FlexAlign.SpaceAround }) {
        Button('cancel')
          .onClick(() => {
            this.controller.close()
            if (this.cancel) {
              this.cancel()
            }
          }).backgroundColor(0xffffff).fontColor(Color.Black)
        Button('confirm')
          .onClick(() => {
            this.controller.close()
            if (this.confirm) {
              this.confirm()
            }
          }).backgroundColor(0xffffff).fontColor(Color.Red)
      }.margin({ bottom: 10 })
    }
  }
}

创建构造器,与装饰器呼应相连。页面内需要在构造器内进行接收,同时创建相应的函数操作。

@Entry
@Component
struct CustomDialogUser {
  dialogController: CustomDialogController = new CustomDialogController({
    builder: CustomDialogExample({
      cancel: ()=> { this.onCancel() },
      confirm: ()=> { this.onAccept() },
    }),
  })

  onCancel() {
    console.info('Callback when the first button is clicked')
  }

  onAccept() {
    console.info('Callback when the second button is clicked')
  }

  build() {
    Column() {
      Button('click me')
        .onClick(() => {
          this.dialogController.open()
        })
    }.width('100%').margin({ top: 5 })
  }
}
2、CustomContentDialog

使用CustomContentDialog自定义弹出框,可在此自定义内容区弹出框,同时支持定义操作区按钮样式。从API version 12开始支持使用。

名称

类型

必填

装饰器类型

说明

controller

CustomDialogController

-

弹出框控制器。

说明: 未使用@Require装饰,构造时不强制校验参数。

contentBuilder

() => void

@BuilderParam

弹出框内容。

primaryTitle

ResourceStr

-

弹出框标题。

secondaryTitle

ResourceStr

-

弹出框辅助文本。

localizedContentAreaPadding

LocalizedPadding

-

弹出框内容区内边距。

contentAreaPadding

Padding

-

弹出框内容区内边距。设置了localizedContentAreaPadding属性时该属性不生效。

buttons

ButtonOptions[]

-

弹出框操作区按钮,最多支持4个按钮。

theme

Theme| CustomTheme

-

主题信息,可以是CustomTheme或从onWillApplyTheme中获取的Theme实例。

themeColorMode

ThemeColorMode

-

自定义弹窗深浅色模式。

支持自定义内容弹出框,包含contentBuilder、buttons等内容。和@CustomDialog装饰器一样,CustomContentDialog也可以添加按钮和数据,如果需要完全自定义弹框样式,可以只设置contentBuilder函数参数用来实现自定义弹框。

import { CustomContentDialog } from '@kit.ArkUI'

@Entry
@Component
struct Index {
  dialogController: CustomDialogController = new CustomDialogController({
    builder: CustomContentDialog({
      primaryTitle: '标题',
      secondaryTitle: '辅助文本',
      contentBuilder: () => {
        this.buildContent();
      },
      buttons: [
        { 
          value: '按钮1',
          buttonStyle: ButtonStyleMode.TEXTUAL, 
          action: () => {
            console.info('Callback when the button is clicked')
          }
        },
        {
          value: '按钮2',
          buttonStyle: ButtonStyleMode.TEXTUAL,
          role: ButtonRole.ERROR
        }
      ],
    }),
  });

  build() {
    Column() {
      Button("支持自定义内容弹出框")
        .onClick(() => {
          this.dialogController.open()
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
  
  // 自定义弹出框的内容区
  @Builder
  buildContent(): void {
    Column() {
      Text('内容区')
    }
    .width('100%')
  }
}

不依赖UI组件的全局自定义弹出框 (openCustomDialog)

先对于CustomDialogController,官方更推荐我们使用openCustomDialog来实现自定义弹出框。

由于CustomDialogController在使用上存在诸多限制,不支持动态创建也不支持动态刷新,在相对较复杂的应用场景中推荐使用UIContext中获取到的PromptAction对象提供的openCustomDialog接口来实现自定义弹出框。

弹出框(openCustomDialog)存在两种入参方式创建自定义弹出框:

  • openCustomDialog(传参为ComponentContent形式):通过ComponentContent封装内容可以与UI界面解耦,调用更加灵活,可以满足开发者的封装诉求。拥有更强的灵活性,弹出框样式是完全自定义的,且在弹出框打开之后可以使用updateCustomDialog方法动态更新弹出框的一些参数。
  • openCustomDialog(传builder的形式):相对于ComponentContent,builder必须要与上下文做绑定,与UI存在一定耦合。此方法有用默认的弹出框样式,适合于开发者想要实现与系统弹窗默认风格一致的效果。
1、初始化弹出框配置

获取PromptAction对象,初始化弹出框配置,可在配置中修改弹窗位置,动画等相关配置。

创建ComponentContent,ComponentContent用于定义自定义弹出框的内容。其中,wrapBuilder(radioDialogView)封装自定义组件。

  // 设置对话框内容组件(支持链式调用)
  init(context: UIContext, radioSelectBean: RadioSelectBean): RadioAppDialog {
    this.contentNode = new ComponentContent(context, wrapBuilder<[RadioSelectBean]>(radioDialogView), radioSelectBean);
    this.promptAction = context.getPromptAction();
    this.options = {
      alignment: DialogAlignment.Bottom,
      transition: TransitionEffect.move(TransitionEdge.BOTTOM)
        .animation({ duration: 300 }),
    }
    return this
  }
2、打开自定义弹出框。

通过调用openCustomDialog接口打开的弹出框默认为customStyle为true的弹出框,即弹出框的内容样式完全按照contentNode自定义样式显示。

 // 显示自定义对话框
  show() {
    if (this.contentNode !== null) {
      this.promptAction?.openCustomDialog(this.contentNode, this.options)
        .then(() => {
          console.info('打开自定义对话框完成')
        })
        .catch((error: BusinessError) => {
          // 错误处理:获取错误码和信息
          let message = (error as BusinessError).message;
          let code = (error as BusinessError).code;
          console.error(`打开对话框参数错误,错误码:${code},信息:${message}`);
        })
    }
  }
3、关闭自定义弹出框

关闭弹出框之后若需要释放对应的ComponentContent,则需要调用ComponentContent的dispose方法。

tip:关闭弹出框需要传人待关闭的ComponentContent对象。

 // 关闭自定义对话框
  close() {
    if (this.contentNode !== null) {
      this.promptAction?.closeCustomDialog(this.contentNode)
        .then(() => {
          this.contentNode?.dispose()
          console.info('关闭自定义对话框完成')
        })
        .catch((error: BusinessError) => {
          let message = (error as BusinessError).message;
          let code = (error as BusinessError).code;
          console.error(`关闭对话框参数错误,错误码:${code},信息:${message}`);
        })
    }
  }
4、更新自定义弹出框的内容

若需要更新弹出框中自定义组件的内容可以通过ComponentContent提供的update方法来实现。这里传人的数据对象就事显示的时候传人的数据。

  //更新对话框数据
  updateData(radioSelectBean: RadioSelectBean) {
    this.contentNode?.update(radioSelectBean)
  }
5、完整代码
// 导入ArkUI的对话框操作模块和基础服务错误类型
import { ComponentContent, curves, PromptAction, promptAction } from "@kit.ArkUI";
import { BusinessError } from "@kit.BasicServicesKit";
import { RadioSelectBean } from "../model/HomeModel";
import { radioDialogView } from "../view/GlobalBuildView";

// 自定义单选对话框类
export class RadioAppDialog {
  // 单例实例
  private static instance: RadioAppDialog;
  // 静态属性声明
  contentNode?: ComponentContent<Object>; // 对话框内容组件
  options?: promptAction.BaseDialogOptions; // 对话框基础配置选项
  promptAction?: PromptAction

  // 私有化构造函数
  private constructor() {
    console.info('创建自定义对话框单例');
  }

  /**
   * 获取单例实例(静态方法)
   * @returns 返回全局唯一实例
   */
  public static getInstance(): RadioAppDialog {
    if (!RadioAppDialog.instance) {
      RadioAppDialog.instance = new RadioAppDialog();
    }
    return RadioAppDialog.instance;
  }

  /**
   * 重置单例实例(用于测试或特殊场景)
   */
  public static resetInstance(): void {
    RadioAppDialog.instance = new RadioAppDialog();
  }


  // 设置对话框内容组件(支持链式调用)
  init(context: UIContext, radioSelectBean: RadioSelectBean): RadioAppDialog {
    this.contentNode = new ComponentContent(context, wrapBuilder<[RadioSelectBean]>(radioDialogView), radioSelectBean);
    this.promptAction = context.getPromptAction();
    this.options = {
      alignment: DialogAlignment.Bottom,
      transition: TransitionEffect.move(TransitionEdge.BOTTOM)
        .animation({ duration: 300 }),
    }
    return this
  }

  // 设置对话框选项(支持链式调用)
  setOptions(options: promptAction.BaseDialogOptions): RadioAppDialog {
    this.options = options;
    return this;
  }

  //更新对话框数据
  updateData(obj?: Object) {
    this.contentNode?.update(obj)
  }


  // 显示自定义对话框
  show() {
    if (this.contentNode !== null) {
      this.promptAction?.openCustomDialog(this.contentNode, this.options)
        .then(() => {
          console.info('打开自定义对话框完成')
        })
        .catch((error: BusinessError) => {
          // 错误处理:获取错误码和信息
          let message = (error as BusinessError).message;
          let code = (error as BusinessError).code;
          console.error(`打开对话框参数错误,错误码:${code},信息:${message}`);
        })
    }
  }

  // 关闭自定义对话框
  close() {
    if (this.contentNode !== null) {
      this.promptAction?.closeCustomDialog(this.contentNode)
        .then(() => {
          this.contentNode?.dispose()
          console.info('关闭自定义对话框完成')
        })
        .catch((error: BusinessError) => {
          let message = (error as BusinessError).message;
          let code = (error as BusinessError).code;
          console.error(`关闭对话框参数错误,错误码:${code},信息:${message}`);
        })
    }
  }

  // 更新对话框配置
  updateDialog(options: promptAction.BaseDialogOptions) {
    if (this.contentNode !== null) {
      this.promptAction?.updateCustomDialog(this.contentNode, options)
        .then(() => {
          console.info('更新对话框配置完成')
        })
        .catch((error: BusinessError) => {
          let message = (error as BusinessError).message;
          let code = (error as BusinessError).code;
          console.error(`更新对话框参数错误,错误码:${code},信息:${message}`);
        })
    }
  }
}

http://www.kler.cn/a/592942.html

相关文章:

  • DockerTLS加密/不加密传输
  • 科技快讯 | AI助手也“摆烂”;国内独有“玻璃光盘”技术发布;“全国消协智慧315平台”正式上线
  • Leetcode-100 回溯法-全排列
  • 实用工具-Another Redis Desktop Manager介绍
  • 2023南京理工大学计算机复试上机真题
  • 安全基线-rm命令防护
  • 【论文阅读】Adversarial Patch Attacks on Monocular Depth Estimation Networks
  • 【总结】Pytest vs Behave,BDD 测试框架哪家强?
  • MyBatis 配置文件解析使用了哪些设计模式
  • Hessian 矩阵是什么
  • Quartus + VScode 实现模块化流水灯
  • MySQL-单表查询
  • Java 大视界 -- 基于 Java 的大数据分布式存储系统的数据备份与恢复策略(139)
  • 如何在electron中注册快捷键?
  • 【机器学习】强化学习
  • securtiy_crt访问ubuntu报Key exchange failed问题
  • PostgreSQL 视图
  • AI训练如何获取海量数据,论平台的重要性
  • Python实现WYY音乐下载
  • Redis复制(replica)主从模式