【鸿蒙应用ArkTS开发系列】-自定义底部菜单列表弹窗

文章目录

  • 前言
  • 创建Demo工程
    • 创建dialog 文件夹
    • 创建ListMenu 接口
    • 创建自定义弹窗 ListMenuDialog
    • 使用自定义弹窗
  • 打包测试
  • 效果演示
    • 默认效果
    • 菜单带图标效果
    • 设置文本颜色效果
    • 不同文本颜色效果
    • 无标题效果

前言

上一篇文章中我们实现了选择图片、选择文件、拍照的功能 。
链接在这里,大家有兴趣可以点击 《【鸿蒙应用ArkTS开发系列】- 选择图片、文件和拍照功能实现》 。

之前的效果
在这里插入图片描述
这一节我们要实现的效果
在这里插入图片描述

上一节 我们是在页面布局中使用三个按钮来作为入口,但是有些场景,我们希望应用以底部菜单弹窗的形式来与用户进行操作交互。那在鸿蒙原生应用中,一个自定义的底部菜单列表弹窗应该怎么实现呢,这一节,我们来讲下这个基础知识。

创建Demo工程

我们使用Empty Ability 模板创建一个Demo工程。
在这里插入图片描述
在这里插入图片描述

创建dialog 文件夹

在这里插入图片描述

创建ListMenu 接口

在src->main->ets ->dialog 文件夹下创建ListMenu.ets文件,完整代码如下:

/*** 菜单*/
export interface ListMenu {id: string;text: string | Resource;icon?: Resource;fontColor?: ResourceColor;onItemClick?: () => void;
}

这里我们对底部菜单列表的菜单选项数据进行抽象,抽取出通用字段:

  • id 唯一字段
  • text 显示的菜单文本
  • icon 文本左侧显示的图标,非必传
  • fontColor 文本颜色 非必传
  • onItemClick 点击事件

下面我们来看下自定义弹窗类的代码实现。

创建自定义弹窗 ListMenuDialog

在src->main->ets ->dialog 文件夹下创建ListMenuDialog.ets文件,完整代码如下:

/*** 自定义底部列表菜单弹窗*/
import { ListMenu } from './ListMenu';@CustomDialog
export struct ListMenuDialog {@Prop title: string = '';@State titleVisible: boolean = true;@State menuArray: ListMenu[] = [];controller: CustomDialogController;onCancel?: () => void;@StylesitemPressedStyle() {.backgroundColor('#e2e2e2')}@StylesitemNormalStyle() {.backgroundColor(Color.White)}build() {Column() {Text(this.title).fontColor('#999999').fontSize(14).margin({ top: 10 }).maxLines(1).visibility(this.titleVisible ? Visibility.Visible : Visibility.None)if (this.menuArray.length > 0) {Scroll() {Column() {ForEach(this.menuArray, (item: ListMenu, index: number) => {this.MenuItem(item, index)}, (index: number) => {return index.toString();})}}.backgroundColor(Color.White).borderRadius(8).margin({ top: 10 }).constraintSize({maxHeight: '40%'})}Text('取消').width('100%').height(50).fontColor(Color.Black).fontSize(16).margin({ top: 15 }).backgroundColor(Color.White).textAlign(TextAlign.Center).borderRadius(8).stateStyles({normal: this.itemNormalStyle,pressed: this.itemPressedStyle}).onClick(() => {if (this.controller) {this.controller.close();}if (this.onCancel) {this.onCancel();}})}.padding(10).alignItems(HorizontalAlign.Center).width('100%').backgroundColor('#f8f8f8').borderRadius({topLeft: 15,topRight: 15})}@BuilderMenuItem(item: ListMenu, index: number) {Row() {Image(item.icon).width(30).height(30).visibility(item.icon ? Visibility.Visible : Visibility.None)Text(item.text).fontColor(item.fontColor ? item.fontColor : Color.Black).fontSize(16).textAlign(TextAlign.Center).margin({ left: 5 })}.width('100%').height(50).alignItems(VerticalAlign.Center).justifyContent(FlexAlign.Center).borderStyle({ bottom: BorderStyle.Solid }).borderColor('#f8f8f8').borderWidth({bottom: index === this.menuArray.length - 1 ? 0 : 1}).stateStyles({normal: this.itemNormalStyle,pressed: this.itemPressedStyle}).onClick(() => {if (this.controller) {this.controller.close();}if (item.onItemClick) {item.onItemClick();}})}
}

下面我们对这个自定义弹窗代码进行一些讲解:

  1. 首先我们定义一个ListMenuDialog 的结构体;
    export struct ListMenuDialog 。

  2. 使用@CustomDialog装饰器
    我们使用@CustomDialog装饰这个ListMenuDialog 结构体,表明我们这个结构体是一个自定义对话框。

  3. 定义自定义弹窗控制器CustomDialogController
    通过定义CustomDialogController,在弹窗内部可以触发弹窗的打开跟关闭。

  4. title
    弹窗标题,这里定义为Prop, 可以与页面进行状态同步,对于有弹窗标题动态修改的场景,可以使用到。

  5. titleVisible
    控制标题是否显示,如果弹窗没有标题,通过传递false进行设置标题不显示。

  6. menuArray
    列表菜单数据源 ,通过使用ForEach进行遍历调用 我们MenuItem子项 绘制列表UI。

  7. MenuItem
    这个是菜单项UI布局方法,我们使用@Builder装饰。

  8. 分隔线
    通过给Item设置 border,绘制底部边框来实现分隔线的效果。

  9. 菜单按下点击色
    通过设置 stateStyles,给Item配置两个@Style装饰的样式itemNormalStyle 跟itemPressedStyle,来实现按下Item显示一个点击效果。

这样我们就完成了一个自定义底部菜单列表弹窗,下面我们在页面中来进行实际使用。

使用自定义弹窗

我们在Index.ets 中添加如下代码:

import { ListMenu } from '../dialog/ListMenu';
import { ListMenuDialog } from '../dialog/ListMenuDialog';@Entry
@Component
struct Index {@State message: string = '点击弹窗';private customDialogController: CustomDialogController;build() {Row() {Column() {Text(this.message).fontSize(50).fontWeight(FontWeight.Bold).onClick(this.showBottomDialog.bind(this))}.width('100%')}.height('100%')}showBottomDialog() {const menuList: ListMenu[] = [{id: '1',text: '选择图片',fontColor: $r("app.color.blue_089ed9"),onItemClick: () => {console.log('点击了选择图片');}},{id: '2',text: '选择文件',fontColor: $r("app.color.blue_089ed9"),onItemClick: () => {console.log('点击了选择文件');}},{id: '3',text: '拍照',fontColor: $r("app.color.blue_089ed9"),onItemClick: () => {console.log('点击了拍照');}},];this.customDialogController = new CustomDialogController({builder: ListMenuDialog({title: '多媒体操作',menuArray: menuList,controller: this.customDialogController}),cancel: () => {console.log('点击了取消');},autoCancel: true,alignment: DialogAlignment.Bottom,customStyle: true});this.customDialogController.open();}hideBottomDialog() {this.customDialogController.close();}
}

我们定义了一个CustomDialogController 弹窗控制器,这里我们对CustomDialogController的一些属性进行下讲解,

  • builder:
    这个是设置一个@CustomDialog装饰的弹窗对象,这里使用我们上面创建的ListMenuDialog自定义弹窗。
  • cancel:
    这个是弹窗取消时候会触发的回调函数。
  • autoCancel:
    true 可以通过触击弹窗外空白处使得弹窗关闭,false ,则不可以。
  • alignment:
    这个是弹窗的显示位置,这里我们设置为DialogAlignment.Bottom,在底部弹出。
  • customStyle :
    这个是是否自定义弹窗样式,我们是自定义弹窗,设置为true即可。

我们通过构建一个弹窗控制器来控制弹窗的显示跟关闭,通过构建ListMenuDialog对象来配置弹窗数据源和显示样式,包括标题,标题是否显示,弹窗菜单的样式。 那接下来我们直接运行demo看下效果。

打包测试

打包安装到真机上,需要我们给项目配置签名信息。我们点击File -> Project Structure ->Project ,选择 Signing Configs面板,勾选 Support HarmonyOS 跟Automatically generate signature,自动生成调试签名,生成完毕后,运行安装到手机上。

效果演示

默认效果

const menuList: ListMenu[] = [{id: '1',text: '选择图片',fontColor: $r("app.color.blue_089ed9")},

在这里插入图片描述

菜单带图标效果

const menuList: ListMenu[] = [{id: '1',text: '选择图片',icon: $r('app.media.ic_picture'),onItemClick: () => {console.log('点击了选择图片');}},{id: '2',text: '选择文件',icon: $r('app.media.ic_file'),onItemClick: () => {console.log('点击了选择文件');}}]

在这里插入图片描述

设置文本颜色效果

在这里插入图片描述

const menuList: ListMenu[] = [{id: '1',text: '选择图片',fontColor: $r("app.color.blue_089ed9"),onItemClick: () => {console.log('点击了选择图片');}},{id: '2',text: '选择文件',fontColor: $r("app.color.blue_089ed9"),onItemClick: () => {console.log('点击了选择文件');}}
]

不同文本颜色效果

const menuList: ListMenu[] = [{id: '1',text: '选择图片',fontColor: $r("app.color.blue_089ed9"),onItemClick: () => {console.log('点击了选择图片');}},{id: '2',text: '选择文件',fontColor: $r("app.color.green_2f7e04"),onItemClick: () => {console.log('点击了选择文件');}}
]

在这里插入图片描述

无标题效果

 builder: ListMenuDialog({menuArray: menuList,controller: this.customDialogController}),

在这里插入图片描述

大家也可以 在 ListMenu中增加一些其他的字段属性来拓展弹窗样式,比如图标的大小、文本的对齐方式等等。

那本章内容就到此结束,谢谢大家的阅读! 有疑问的可以在评论区留言交流。

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

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

相关文章

每日一练2023.12.1——输出GPLT【PTA】

题目链接:L1-023 输出GPLT 题目要求: 给定一个长度不超过10000的、仅由英文字母构成的字符串。请将字符重新调整顺序,按GPLTGPLT....这样的顺序输出,并忽略其它字符。当然,四种字符(不区分大小写&#x…

对小程序的初了解

WXML和HTML的区别 标签名称不同 HTML&#xff1a;div、a、span、img WXML&#xff1a;view、text、image、navigator 属性节点不同 <a href"#">超链接</a> <navigator url"/pages/home/home"></navigator> 提供了类似vue的…

计算机视觉(OpenCV+TensorFlow)

计算机视觉&#xff08;OpenCVTensorFlow&#xff09; 文章目录 计算机视觉&#xff08;OpenCVTensorFlow&#xff09;前言7. 图像直方图绘制直方图绘制直方图有两种方式&#xff1a; 掩膜 8. 直方图均衡化直方图均衡化的介绍直方图均衡化的步骤自适应直方图均衡化 9. 图像转换…

SAP_ABAP_编程基础_数据集_创建并填充摘录数据集 / 处理摘录数据集

SAP ABAP 顾问&#xff08;开发工程师&#xff09;能力模型_Terry谈企业数字化的博客-CSDN博客文章浏览阅读494次。目标&#xff1a;基于对SAP abap 顾问能力模型的梳理&#xff0c;给一年左右经验的abaper 快速成长为三年经验提供超级燃料&#xff01;https://blog.csdn.net/j…

webshell之自建漏洞免杀

今天主要讲解&#xff0c;如何利用通用漏洞来进行命令执行&#xff0c;从而达到免杀效果 常规反序列化免杀 这种方式就相当于直接触发提供一个反序列化漏洞入口&#xff0c;但是能否被利用&#xff0c;还是在于服务端本身是否存在反序列化漏洞&#xff0c;下面给了一个例子&a…

基于机器学习的笔记本电脑导购系统

目 录 中英文摘要 第一章 概述 1 1.1 课题开发背景及意义 1 1.2 课题研究现状 2 1.3 课题主要研究内容 3 第二章 需求分析 4 2.1 功能需求分析 4 2.2 可行性分析 10 2.3 流程分析 11 2.4 数据流图 13 2.5 性能需求分析 15 第三章 开发技术及工具 16 3.1 系统开发模式技术 16 3…

《凤凰项目》读书笔记

文章目录 一、书名和作者二、书籍概览2.1 主要论点和结构2.2 目标读者和应用场景 三、核心观点与主题3.1 DevOps的核心原则与文化变革3.2 持续交付与自动化3.3 变更管理与风险控制3.4 关键绩效指标与持续改进 四、亮点与启发4.1 最有影响的观点4.2 对个人专业发展的启示 五、批…

【Linux--进程控制】

目录 一、进程等待1.1进程等待方法1.2获取子进程status 二、进程替换2.1单进程版本--最简单得程序替换2.2 进程替换得原理2.3 多进程版本--验证各种程序替换接口2.4 总结 一、进程等待 1.1进程等待方法 问题1&#xff1a;进程等待是什么&#xff1f; 通过系统调用wait/waitpi…

Java 定时任务

Java 定时任务 为什么需要定时任务&#xff1f; 我们来看一下几个非常常见的业务场景&#xff1a; 某系统凌晨 1 点要进行数据备份。某电商平台&#xff0c;用户下单半个小时未支付的情况下需要自动取消订单。某媒体聚合平台&#xff0c;每 10 分钟动态抓取某某网站的数据为…

五、关闭三台虚拟机的防火墙和Selinux

目录 1、关闭每台虚拟机的防火墙 2、关闭每台虚拟机的Selinux 2.1 什么是SELinux

使用SpringBoot和ZXing实现二维码生成与解析

一、ZXing简介 ZXing是一个开源的&#xff0c;用Java实现的多种格式的1D/2D条码图像处理库。它包含了用于解析多种格式的1D/2D条形码的工具类&#xff0c;目标是能够对QR编码&#xff0c;Data Matrix, UPC的1D条形码进行解码。在二维码编制上&#xff0c;ZXing巧妙地利用构成计…

系列十四、SpringBoot的jar包可以直接运行原理分析

一、普通jar包运行 vs SpringBoot jar包运行 1.1、普通jar包运行 general-test-1.0-SNAPSHOT.jar是位于D盘的一个普通的jar包&#xff0c;是idea中一个普通的maven项目通过package打包生成&#xff0c;为了方便测试我把它拷贝到D盘了。 java -jar general-test-1.0-SNAPSHOT.j…

springboot虚拟请求——测试

springboot虚拟请求 表现层测试 web环境模拟测试 虚拟请求状态匹配——执行状态的匹配 Testvoid testStatus(Autowired MockMvc mvc) throws Exception { // //http://localhost:8080/books// 创建一个虚拟请求&#xff0c;当前访问的是booksMockHttpServletRequestBui…

不会代码(零基础)学语音开发(学习工具)

学习&#xff0c;要选择适合自己的&#xff0c;好的学习工具至关重要。就像读书&#xff0c;要读好书一样。 自己不会选&#xff0c;可以参考前辈&#xff0c;找chatgpt等来帮忙。充分利用好周边的资源。 秉承着GPT和前辈们的经验之谈&#xff0c;开始选择语音开发产品&#…

localStorage 和sessionStorage

localStorage 和 sessionStorage 是浏览器提供的两种客户端存储数据的方式&#xff1a; 生命周期&#xff1a; localStorage&#xff1a; 存储在 localStorage 中的数据在浏览器关闭后仍然保留&#xff0c;直到被显式删除或浏览器清除缓存。sessionStorage&#xff1a; 存储在 …

操作系统-输入输出管理

I/O设备的基本概念和分类 I/O就是输入/输出 I/O设备就是可以将数据输入到计算机&#xff0c;或者可以接收计算机输出数据的外部设备&#xff0c;属于计算机中的硬件部件。 I/O设备按使用特性分类 人机交互类外部设备存储设备网络通信设备 I/O设备按传输速率分类 低速设备中…

uniapp-距离distance数字太长,截取保留前3为数字

1.需求 将接口返回的距离的字段&#xff0c;保留三位数显示。 2.实现效果 3.代码&#xff1a; 1.这是接口返回的数据&#xff1a; 2.调取接口&#xff0c;赋值前先处理每条数据的distance <view class"left">距你{{item.distance}}km</view>listFun() …

聚焦数据库Serverless创新,就在2023亚马逊云科技re:Invent

11月28日&#xff0c;亚马逊云科技在其最新的re:Invent 2023大会上宣布了三项重要的serverless创新&#xff0c;这些创新将极大地简化客户在任何规模上分析和管理数据的能力。以下是这些发布的主要要点总结和分析。 Amazon Aurora Limitless Database的新功能&#xff1a; 功能…

播放器开发(七):音视频同步实现

目录 学习课题&#xff1a;逐步构建开发播放器【QT5 FFmpeg6 SDL2】 原理 简单分析&#xff1a; 下图简单描述了在一个播放过程中&#xff0c;假设我们先播放音频&#xff0c;对比一个公共时间轴&#xff0c;视频就会始终比音频慢0.003s。 我们在日常中用一些播放器播放视频…

docker-compose脚本编写及常用命令

安装 linux DOCKER_CONFIG/usr/local/lib/docker/cli-plugins sudo mkdir -p $DOCKER_CONFIG/cli-plugins sudo curl -SL https://521github.com/docker/compose/releases/download/v2.6.1/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose sudo c…