首页
学习
活动
专区
圈层
工具
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

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开始支持使用。

支持自定义内容弹出框,包含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}`);

      })

  }

}

}

  • 发表于:
  • 原文链接https://page.om.qq.com/page/O3ueOO3mkAN-1a_lwvI3tZ7g0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券