鸿蒙UI系统组件18——模态交互框(ModelDialog)

news2024/11/29 22:42:42

1、概 述

模态(Modal)指的是UI组件或视图的一种状态。在模态组件消失前,用户只能对处于模态的组件或视图进行响应,不能操作其他非模态的组件或视图。

ArkUI中可通过使用AlertDialog、CustomDialog、ActionSheet、Popup、Menu、ContextMenu等组件实现模态类弹窗能力。

  • AlertDialog

通常用来展示用户当前需要或必须关注的信息或操作。如用户操作一个敏感行为时响应一个二次确认的弹窗。

  • ActionSheet

当需要用户关注或确认的信息存在列表选择时使用。

  • CustomDialog

当用户需要自定义弹窗内的组件和内容时使用。

  • Popup

用于为指定的组件做信息提示。如点击一个问号图标弹出一段气泡提示。

  • Menu/ContextMenu

用于给指定的组件绑定用户可执行的操作,如长按图标展示操作选项等。

  • 我们可以通过配置参数(例如:CustomDialog的isModal)调整弹窗为非模态弹窗,从而满足不同的使用场景。

  • 移动设备中,子窗模式的弹窗当前无法超出主窗口。

  • 多个弹窗组件先后弹出时,后弹出的组件的层级高于先弹出的层级,退出时按照层级从高到低的顺序逐次退出。

2、全局弹窗

全局弹窗不与任何组件绑定,一般用于针对用户触发的操作进行必要提示时使用。ArkUI当前提供了定制和自定义两类弹窗组件。

  • 定制:AlertDialog、ActionSheet、promptAction.showDialog、promptAction.showActionMenu。使用此类组件需要指定显示的文本内容和按钮操作即可完成简单的交互效果。

  • 自定义:CustomDialog、promptAction.openCustomDialog。需要根据场景传入自定义组件填充在弹窗中实现自定义的弹窗内容。

下面以AlertDialog、ActionSheet 和 CustomDialog为例说明相应的弹窗效果与使用方法。

2.1、AlertDialog

AlertDialog: 警告弹窗,需要向用户提问或得到用户的许可。

  • 警告弹窗用来提示重要信息,但会中断当前任务,尽量提供必要的信息和有用的操作。

  • 避免仅使用警告弹窗提供信息,用户不喜欢被信息丰富但不可操作的警告打断。

  • 必选内容包含:标题、可选信息文本、最多3个按钮。

  • 可选内容包含:输入框、icon、checkBox和HelpButton。

图片

@Entry@Componentstruct AlertDialogExample {  build() {    Column({ space: 5 }) {      Button('two button dialog')        .onClick(() => {          AlertDialog.show(            {              title: 'title',              subtitle: 'subtitle',              message: 'text',              autoCancel: true,              alignment: DialogAlignment.Bottom,              gridCount: 4,              offset: { dx: 0, dy: -20 },              primaryButton: {                value: 'cancel',                action: () => {                  console.info('Callback when the first button is clicked')                }              },              secondaryButton: {                enabled: true,                defaultFocus: true,                style: DialogButtonStyle.HIGHLIGHT,                value: 'ok',                action: () => {                  console.info('Callback when the second button is clicked')                }              }            }          )        }).backgroundColor(0x317aff)    }.width('100%').margin({ top: 5 })  }}

2.2、ActionSheet

ActionSheet: 列表选择弹窗。

  • 适合展示多个操作项,尤其是除了操作列表以外没有其他的展示内容。

图片

@Entry@Componentstruct ActionSheetExample {  build() {    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {      Button('Click to Show ActionSheet')        .onClick(() => {          ActionSheet.show({            title: 'ActionSheet title',            subtitle: 'ActionSheet subtitle',            message: 'message',            autoCancel: true,            confirm: {              defaultFocus: true,              value: 'Confirm button',              action: () => {                console.log('Get Alert Dialog handled')              }            },            alignment: DialogAlignment.Bottom,            offset: { dx: 0, dy: -10 },            sheets: [              {                title: 'apples',                action: () => {                  console.log('apples')                }              },              {                title: 'bananas',                action: () => {                  console.log('bananas')                }              },              {                title: 'pears',                action: () => {                  console.log('pears')                }              }            ]          })        })    }.width('100%')    .height('100%')  }}

2.3、CustomDialog

当我们需要自定义弹窗的内容和样式时,可选择CustomDialog。【更建议使用promptAction.openCustomDialog】

图片

// xxx.ets@CustomDialog@Componentstruct CustomDialogExample {  @Link textValue: string  @Link inputValue: string  controller?: CustomDialogController  cancel: () => void = () => {  }  confirm: () => void = () => {  }  build() {    Column() {      Text('Change text').fontSize(20).margin({ top: 10, bottom: 10 })      TextInput({ placeholder: '', text: this.textValue }).height(60).width('90%')        .onChange((value: string) => {          this.textValue = value        })      Text('Whether to change a text?').fontSize(16).margin({ bottom: 10 })      Flex({ justifyContent: FlexAlign.SpaceAround }) {        Button('cancel')          .onClick(() => {            if (this.controller != undefined) {              this.controller.close()              this.cancel()            }          }).backgroundColor(0xffffff).fontColor(Color.Black)        Button('confirm')          .onClick(() => {            if (this.controller != undefined) {              this.inputValue = this.textValue              this.controller.close()              this.confirm()            }          }).backgroundColor(0xffffff).fontColor(Color.Red)      }.margin({ bottom: 10 })    }.borderRadius(10)  }}@Entry@Componentstruct CustomDialogUser {  @State textValue: string = ''  @State inputValue: string = 'click me'  dialogController: CustomDialogController | null = new CustomDialogController({    builder: CustomDialogExample({      cancel: () => {        this.onCancel()      },      confirm: () => {        this.onAccept()      },      textValue: $textValue,      inputValue: $inputValue    }),    cancel: this.exitApp,    autoCancel: true,    onWillDismiss: (dismissDialogAction: DismissDialogAction) => {      console.info("reason=" + JSON.stringify(dismissDialogAction.reason))      console.log("dialog onWillDismiss")      if (dismissDialogAction.reason == DismissReason.PRESS_BACK) {        dismissDialogAction.dismiss()      }      if (dismissDialogAction.reason == DismissReason.TOUCH_OUTSIDE) {        dismissDialogAction.dismiss()      }    },    alignment: DialogAlignment.Bottom,    offset: { dx: 0, dy: -20 },    gridCount: 4,    customStyle: false,    cornerRadius: 10,  })  // 在自定义组件即将析构销毁时将dialogController置空  aboutToDisappear() {    this.dialogController = null // 将dialogController置空  }  onCancel() {    console.info('Callback when the first button is clicked')  }  onAccept() {    console.info('Callback when the second button is clicked')  }  exitApp() {    console.info('Click the callback in the blank area')  }  build() {    Column() {      Button(this.inputValue)        .onClick(() => {          if (this.dialogController != null) {            this.dialogController.open()          }        }).backgroundColor(0x317aff)    }.width('100%').margin({ top: 5 })  }}

3、交互辅助弹窗

3.1、气泡Popup

当点击目标组件或交互区时,弹出内容在其他内容之上,可使用Popup来指示当前功能如何操作。

图片

@Entry@Componentstruct PopupExample {  @State handlePopup: boolean = false  build() {    Flex({ direction: FlexDirection.Column }) {      // PopupOptions 类型设置弹框内容      Button('PopupOptions')        .onClick(() => {          this.handlePopup = !this.handlePopup        })        .bindPopup(this.handlePopup, {          message: 'This is a popup with PopupOptions',          placementOnTop: true,          showInSubWindow: false,          primaryButton: {            value: 'confirm',            action: () => {              this.handlePopup = !this.handlePopup              console.info('confirm Button click')            }          },          // 第二个按钮          secondaryButton: {            value: 'cancel',            action: () => {              this.handlePopup = !this.handlePopup              console.info('cancel Button click')            }          },          onStateChange: (e) => {            console.info(JSON.stringify(e.isVisible))            if (!e.isVisible) {              this.handlePopup = false            }          }        })        .position({ x: 100, y: 150 })    }.width('100%').padding({ top: 5 })  }}

3.2、菜单Menu

很多时候需要通过交互弹出一些菜单选项,用于用户操作。此时可通过Menu和MenuItem组件组合成需要弹出的菜单选项内容,然后借助bindMenu和bindContextMenu方法将菜单和组件绑定。他们的主要区别如下:

  • bindMenu:无需预览图场景,需要在非子窗场景显示。

  • bindContextMenu: 需要预览图场景使用,只能在子窗中显示。

👉🏻 bindMenu

一种临时性弹出组件,用于展示用户可执行的操作。

    ⭐️ 一级Menu样式如下:

图片

    ⭐️ 多级Menu样式如下:

图片

代码示例如下:

@Entry@Componentstruct Index {  @State select: boolean = true  @Builder  MyMenu() {    Menu() {      MenuItem({ content: "菜单选项" })      MenuItem({ content: "菜单选项" })      MenuItem({ content: "菜单选项" })      MenuItem({ content: "菜单选项" })    }  }  build() {    Row() {      Column() {        Text('click to show menu')          .fontSize(50)          .fontWeight(FontWeight.Bold)      }      .bindMenu(this.MyMenu)      .width('100%')    }    .height('100%')  }}

👉🏻 bindContextMenu

 内容包括菜单、预览图、蒙层(通常在长按桌面图标时使用)

    ⭐️ 相对父组件区域弹出样式如下:

图片

    ⭐️ 相对右键点击位置弹出样式如下:

图片

代码示例如下:

@Entry@Componentstruct Index {  @State select: boolean = true  @Builder  MyMenu(){    Menu() {      MenuItem({ content: "菜单选项" })      MenuItem({ content: "菜单选项" })      MenuItem({ content: "菜单选项" })      MenuItem({ content: "菜单选项" })    }  }  build() {    Row() {      Column() {        Text('click to show menu')          .fontSize(50)          .fontWeight(FontWeight.Bold)      }      .bindContextMenu(this.MyMenu, ResponseType.LongPress,{        placement: Placement.Left,        preview: MenuPreviewMode.IMAGE      })      .width('100%')    }    .height('100%')  }}

4、类PC场景

在2in1设备上,使用模态类弹窗时,会出现超出主窗口显示的场景,如下图所示。

图片

我们可通过支持子窗口和默认子窗口实现超出应用界面效果。

4.1、支持子窗口

自定义弹窗(CustomDialog)、警告弹窗(AlertDialog)、列表选择弹窗(ActionSheet)、气泡提示(Popup)可通过showInSubWindow设置弹窗或气泡在子窗口中,从而实现超出主窗口的显示效果。示例代码如下(37行):​​​​​​​

// xxx.ets    @CustomDialogstruct CustomDialogExample {  controller?: CustomDialogController  cancel: () => void = () => {  }  confirm: () => void = () => {  }  build() {    Column() {      Text('可展示在主窗口外的弹窗')        .fontSize(30)        .height(100)      Button('点我关闭弹窗')        .onClick(() => {          if (this.controller != undefined) {            this.controller.close()          }        })        .margin(20)    }  }}@Entry@Componentstruct CustomDialogUser {  dialogController: CustomDialogController | null = new CustomDialogController({    builder: CustomDialogExample({      cancel: ()=> { this.onCancel() },      confirm: ()=> { this.onAccept() }    }),    cancel: this.existApp,    autoCancel: true,    alignment: DialogAlignment.Center,    offset: { dx: 0, dy: -20 },    gridCount: 4,    showInSubWindow: true,    isModal: true,    customStyle: false,    cornerRadius: 10,  })  // 在自定义组件即将析构销毁时将dialogController置空  aboutToDisappear() {    this.dialogController = null // 将dialogController置空  }  onCancel() {    console.info('Callback when the first button is clicked')  }  onAccept() {    console.info('Callback when the second button is clicked')  }  existApp() {    console.info('Click the callback in the blank area')  }  build() {    Column() {      Button('click me')        .onClick(() => {          if (this.dialogController != null) {            this.dialogController.open()          }        }).backgroundColor(0x317aff)    }.width('100%').margin({ top: 5 })  }}

4.2、默认子窗口

可使用 bindContextMenu为组件绑定菜单,触发方式为长按或者右键点击,弹出菜单项需要自定义。​​​​​​​

@Entry@Componentstruct ContextMenuExample {  @Builder MenuBuilder() {    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {      Text('Test menu item 1')        .fontSize(20)        .width(100)        .height(50)        .textAlign(TextAlign.Center)      Divider().height(10)      Text('Test menu item 2')        .fontSize(20)        .width(100)        .height(50)        .textAlign(TextAlign.Center)    }.width(100)  }  build() {    Column() {      Text('LongPress for menu')    }    .width('100%')    .margin({ top: 5 })    .bindContextMenu(this.MenuBuilder, ResponseType.LongPress)  }}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

力扣题86~90

题86(中等): python代码 # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class Solution:def partition(self, head: Optional[Li…

JavaEE初阶---网络原理/UDP服务器客户端程序

文章目录 1.网络初识2.网络编程2.1TCP/UDP区别介绍2.2UDP的socket api使用2.3UDP协议里面的服务器客户端程序 1.网络初识 网络和计算机类似:都是属于军用》民用; 网络诞生于美苏争霸时期,当时就感觉核战争一触即发,形式非常严峻…

.NET 8 中的 Mini WebApi

介绍 .NET 8 中的极简 API 隆重登场,重新定义了我们构建 Web 服务的方式。如果您想知道极简 API 的工作原理以及它们如何简化您的开发流程,让我们通过一些引人入胜的示例来深入了解一下。 .NET 极简主义的诞生 想想我们曾经不得不为一个简单的 Web 服务…

在 Kakarot ZkEVM 上使用 Starknet Scaffold 构建应用

Starknet 和 EVM 我们所知的智能合约世界一直围绕着以太坊虚拟机(EVM),其主要语言是 Solidity。 尽管 Starknet 通过 STARKs 为以太坊开辟了新的可能性,但其缺点是它有一个不同的虚拟机 (CairoVM),这要求开发者学习 …

多态的体现

多态:当不同的对象去完成某个行为时会产生出不同的状态多态体现: 在代码运行时,当传递不同类对象时,会调用对应类中的方法。 public class Animal {String name;int age;public Animal(String name, int age){this.name name;t…

docker安装、设置非sudo执行、卸载

安装 sudo snap install docker 设置docker非sudo执行 sudo groupadd docker sudo usermod -aG docker $USER newgrp docker sudo chown root:docker /var/run/docker.sock 卸载docker 1.删除docker及安装时自动安装的所有包 apt-get autoremove docker docker-ce docker-…

Java之多线程的实现(创建)(3种实现方式)(面试高频)

目录 一、多线程的3种实现方式 (1)继承Thread类。 (2)实现Runnable接口。(void run():该方法无返回值、无法抛出异常) (3)实现Callable接口。(V call() throw…

Linux补基础之:网络配置

目录 一、检查主机与虚拟机是否能正常通信 二、网络的连接模式 桥接模式 流程 特点 NAT模式 流程 特点 仅主机 流程 特点 三、修改静态IP 四、可能遇到的问题 防火墙 DNS 五、主机名更改 六、登录服务器 实际的大数据管理中,会有由很多服务器构成的…

Android 原生开发与Harmony原生开发浅析

Android系统 基于Linux ,架构如下 底层 (Linux )> Native ( C层) > FrameWork层 (SystemService) > 系统应用 (闹钟/日历等) 从Android发版1.0开始到现在15,经历了大大小小的变革 从Android6.0以下是个分水岭,6.0之前权限都是直接卸载Manifest中配置 6.0开始 则分普…

初识WebGL

思路&#xff1a; 构建<canvas>画布节点&#xff0c;获取其的实例。使用getWebGLContext() 拿到画布上下文。拿到上下文用clearColor() 设置背景颜色。最后清空canvas画布,是为了清除颜色缓冲区。 html结构&#xff1a; <!DOCTYPE html> <html lang"en&…

w外链如何跳转微信小程序

要创建外链跳转微信小程序&#xff0c;主要有以下几种方法&#xff1a; 使用第三方工具生成跳转链接&#xff1a; 注册并登录第三方外链平台&#xff1a;例如 “W外链” 等工具。前往该平台的官方网站&#xff0c;使用手机号、邮箱等方式进行注册并登录账号。选择创建小程序外…

【华为HCIP实战课程二十一】OSPF区域间汇总配置详解,网络工程师

一、OSPF汇总和默认路由 1、大规模的OSPF网络配置路由汇总,减小路由表的规模。 2、路由汇总讲多条连续的IP前缀汇总成一条路由前缀。 3、可以避免网络中的路由震荡,提高网络的稳定性。 4、ABR/ASBR完成路由汇总。 [R4-ospf-1-area-0.0.0.0]abr-summary 11.1.0.0 255.255.…

在C#中使用指针

C#向开发人员隐藏了大部分基本内存管理操作&#xff0c;因为它使用了垃圾回收器和引用。但是&#xff0c;有时候我们也需要直接访问内存&#xff0c;例如&#xff1a;进行平台调用&#xff0c;性能优化等等。 .Net平台定义了两种主要数据类型&#xff1a;值类型和引用类型&…

前端零基础入门到上班:【Day2】开发环境VSCode安装

VSCode 安装教程&#xff1a;图文保姆教程 引言 在前端开发中&#xff0c;选择合适的代码编辑器是提高工作效率的重要一步。Visual Studio Code&#xff08;简称 VSCode&#xff09;作为一款强大的开源编辑器&#xff0c;因其简洁易用、功能强大、扩展性好而广受开发者喜爱。…

MES系列- 统计过程分析(SPC)实现

MES系列文章目录 ISA-95制造业中企业和控制系统的集成的国际标准-(1) ISA-95制造业中企业和控制系统的集成的国际标准-(2) ISA-95制造业中企业和控制系统的集成的国际标准-(3) ISA-95制造业中企业和控制系统的集成的国际标准-(4) ISA-95制造业中企业和控制系统的集成的国际标准…

面对复杂的软件需求:5大关键策略!

面对软件需求来源和场景的复杂性&#xff0c;有效地管理和处理需求资料是确保项目成功的关键&#xff0c;能够提高需求理解的准确性&#xff0c;增强团队协作和沟通&#xff0c;降低项目风险&#xff0c;提高开发效率。反之&#xff0c;项目可能面临需求理解不准确、团队沟通不…

react 基础学习笔记

1.react 语法 ①数据渲染 函数组件将HTML结构直接写在函数的返回值中 JSX只能有一个根元素 JSX插值写法 插值可以使用的位置 1.标签内容&#xff1b; 2.标签属性 JSX 条件渲染&#xff1a;三目运算符&#xff1b; JSX根据数据进行列表渲染&#xff1a;map()方法&#x…

Elastic Stack - FileBeat 入门浅体验

Filebeat 是 Elastic Stack 中的一个轻量级日志转发器&#xff0c;主要用于收集和转发日志数据。Filebeat 作为代理安装在您的服务器上&#xff0c;可以监控您指定的日志文件或位置&#xff0c;收集日志事件&#xff0c;并将其转发到 Elasticsearch 或 Logstash 进行索引。 一…

XCode16中c++头文件找不到解决办法

XCode16中新建Framework&#xff0c;写完自己的c代码后&#xff0c;提示“<string> file not found”等诸如此类找不到c头文件的错误。 工程结构如下&#xff1a; App是测试应用&#xff0c;BoostMath是Framework。基本结构可以参考官方demo&#xff1a;Mix Swift and …

“循环购体系:创新消费回馈模式引领电商新风尚“

各位听众&#xff0c;你们好&#xff0c;我是吴军&#xff0c;今天我想与你们分享一种创新且引人注目的商业模式——循环购体系。这是一种融合了消费回馈与积分制度的新型购物模式&#xff0c;它在顾客与商家之间搭建了一个全新的、互动性强的桥梁。 在循环购体系的运作中&…