【鸿蒙应用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();}})}
}
下面我们对这个自定义弹窗代码进行一些讲解:
-
首先我们定义一个ListMenuDialog 的结构体;
export struct ListMenuDialog 。 -
使用@CustomDialog装饰器
我们使用@CustomDialog装饰这个ListMenuDialog 结构体,表明我们这个结构体是一个自定义对话框。 -
定义自定义弹窗控制器CustomDialogController
通过定义CustomDialogController,在弹窗内部可以触发弹窗的打开跟关闭。 -
title
弹窗标题,这里定义为Prop, 可以与页面进行状态同步,对于有弹窗标题动态修改的场景,可以使用到。 -
titleVisible
控制标题是否显示,如果弹窗没有标题,通过传递false进行设置标题不显示。 -
menuArray
列表菜单数据源 ,通过使用ForEach进行遍历调用 我们MenuItem子项 绘制列表UI。 -
MenuItem
这个是菜单项UI布局方法,我们使用@Builder装饰。 -
分隔线
通过给Item设置 border,绘制底部边框来实现分隔线的效果。 -
菜单按下点击色
通过设置 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中增加一些其他的字段属性来拓展弹窗样式,比如图标的大小、文本的对齐方式等等。
那本章内容就到此结束,谢谢大家的阅读! 有疑问的可以在评论区留言交流。
相关文章:

【鸿蒙应用ArkTS开发系列】-自定义底部菜单列表弹窗
文章目录 前言创建Demo工程创建dialog 文件夹创建ListMenu 接口创建自定义弹窗 ListMenuDialog使用自定义弹窗 打包测试效果演示默认效果菜单带图标效果设置文本颜色效果不同文本颜色效果无标题效果 前言 上一篇文章中我们实现了选择图片、选择文件、拍照的功能 。 链接在这里…...

yolov8添加ca注意力机制
创建文件 coordAtt.py 位置:ultralytics/nn/modules/coordAtt.py ###################### CoordAtt #### start by AI&CV ############################### # https://zhuanlan.zhihu.com/p/655475515 import torch import torch.nn as nn import t…...
linux java后台启动的几种方式
1.使用 nohup 命令 可以使用 nohup 命令启动 Java 应用程序,使其在后台运行,这样即使退出终端或关闭 SSH 连接,Java 应用程序也能继续运行。nohup java -jar myapp.jar &2.使用 & 符号 使用 & 符号可以将 Java 应用程序放到后台…...
selinux-policy-default(2:2.20231119-2)软件包内容详细介绍(5)
接前一篇文章:selinux-policy-default(2:2.20231119-2)软件包内容详细介绍(4) 4. 重点文件内容解析 (1)control/postist文件 上一回解析了control/postinst文件的部分内容,本回继续往下解析。为了便于理解,再次贴出postinst完整代码: #!/bin/sh set -e# summary o…...

代码随想录二刷 |栈与队列 |理论基础
代码随想录二刷 |栈与队列 |理论基础 栈常用操作 队列常用操作 栈与队列是C标准库中的两个数据结构。 栈 栈先进后出,提供 push 和 pop 等接口,所有元素必须符合先进后出的原则,所以栈不提供走访功能,也不…...

java--接口概述
1.认识接口 ①java提供了一个关键字interface,用这个关键字我们可以定义出一个特殊的结构:接口。 ②注意:接口不能创建对象;接口是用来被类实现(implements)的,实现接口的类称为实现类。 ③一个类可以实现多个接口(接…...

出海风潮:中国母婴品牌征服国际市场的机遇与挑战!
近年来,中国母婴品牌在国内市场蓬勃发展的同时,也逐渐将目光投向国际市场。这一趋势不仅受益于中国经济的崛起,还得益于全球市场对高质量母婴产品的不断需求。然而,面对国际市场的机遇,中国母婴品牌同样面临着一系列挑…...

一文读懂MongoDB的知识点(3),惊呆面试官。
🏆作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。 🏆多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。 🎉欢迎 👍点赞✍评论…...

ssm的“魅力”西安宣传网站(有报告)。Javaee项目。
演示视频: ssm的“魅力”西安宣传网站(有报告)。Javaee项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构,通过Spring SpringMvc MybatisVueLayuiElemen…...
怎么让SecureCRT不自动断开连接
SecureCRT 是一个常用的远程连接工具,它可能会因为会话超时或者其他设置而自动断开连接。要防止 SecureCRT 自动断开连接,你可以尝试以下方法: 1. 更改会话选项: 打开 SecureCRT 并连接到你的远程主机后,依次执行以下…...

介绍几种Go语言开发的IDE
文章目录 1.前言2.几种ide2.1 Goland2.2 VsCode示例 2.3 LiteIDE2.4 Eclipse插件GoClipse2.5 Atom2.6 Vim2.7 Sublime Text 3.总结写在最后 1.前言 Go语言作为一种新兴的编程语言,近年来受到了越来越多的关注。 它以其简洁、高效和并发性能而闻名,被广…...

1、设计模式简介(7大原则,3大类)
设计模式有7个原则:单一职责原则、开闭原则、里氏代换原则、依赖倒转原则、接口隔离原则、合成/聚合复用原则、迪米特法则 1.单一职责原则 单一职责原则又称单一功能原则,它规定一个类只有一个职责。如果有多个职责(功能&#x…...
华为鲲鹏+银河麒麟V10编译FreeSWITCH1.10.9
# uname -r 4.19.90-17.5.ky10.aarch64 本想编译FreeSWITCH1.10.7,但碰到点问题,后来改1.10.9,相对比较顺利,记录如下: 先安装工具/开发库等: yum install -y git yum install -y wget yum install -y au…...

CFS三层靶机内网渗透
CFS三层靶机内网渗透 一、靶场搭建1.基础参数信息2.靶场搭建2.1网卡配置2.2Target1配置2.2.1 网卡配置2.2.2 Target1 BT配置 2.3Target2配置2.3.1 网卡配置2.3.2 Target2 BT配置 2.4Target3配置 二、内网渗透Target11.1信息收集1.1.1IP收集1.1.2端口收集1.1.3目录收集 1.2 webs…...

软件分享--智能照片识别分类软件
智能照片识别分类软件,批量识别图片并分类 自动识别照片类型,分为10个类别:车辆、动物、风景、花卉、建筑、街景、美食、人像、夜景、植物、其它 分类准确率90% 本地运行、不需要联网、没有网络也能用、没有注册码、永久使用 如果你拍摄了上…...

Leetcode—409.最长回文串【简单】
2023每日刷题(四十八) Leetcode—409.最长回文串 强烈吐槽!!! 非常不理解,同样的代码,为什么C跑不了C就跑得了,力扣编译器是对C语言有歧视吗???…...

计算机网络入侵检测技术研究
摘 要 随着网络技术的发展,全球信息化的步伐越来越快,网络信息系统己成为一个单位、一个部门、一个行业,甚至成为一个关乎国家国计民生的基础设施,团此,网络安全就成为国防安全的重要组成部分,入侵检测技术…...

深入学习锁--Synchronized各种使用方法
一、什么是synchronized 在Java当中synchronized通常是用来标记一个方法或者代码块。在Java当中被synchronized标记的代码或者方法在同一个时刻只能够有一个线程执行被synchronized修饰的方法或者代码块。因此被synchronized修饰的方法或者代码块不会出现数据竞争的情况&#x…...

pycharm中绘制一个3D曲线
import numpy as np import matplotlib.pyplot as plt # 中文的设置 import matplotlib as mp1 from mpl_toolkits.mplot3d import Axes3D mp1.rcParams["font.sans-serif"] ["kaiti"] mp1.rcParams["axes.unicode_minus"] False # 数据创建 X…...

人工智能_AI服务器安装清华开源_CHATGLM大语言模型_GLM-6B安装部署_人工智能工作笔记0092
看到的这个开源的大模型,很牛,~关键让我们自己也可以部署体验一把了,虽然不知道具体内部怎么构造的但是,也可以自己使用也挺好. 可以部署在自己的机器上也可以部署在云服务器上. 安装以后,是可以使用python代码进行提问,然后返回结果的,这样就可以实现我们自己的chat应用了, …...

UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...

Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
Java数值运算常见陷阱与规避方法
整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...

手机平板能效生态设计指令EU 2023/1670标准解读
手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读,综合法规核心要求、最新修正及企业合规要点: 一、法规背景与目标 生效与强制时间 发布于2023年8月31日(OJ公报&…...
DiscuzX3.5发帖json api
参考文章:PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下,适配我自己的需求 有一个站点存在多个采集站,我想通过主站拿标题,采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...

一些实用的chrome扩展0x01
简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序,无论是测试应用程序、搜寻漏洞还是收集情报,它们都能提升工作流程。 FoxyProxy 代理管理工具,此扩展简化了使用代理(如 Burp…...
ArcPy扩展模块的使用(3)
管理工程项目 arcpy.mp模块允许用户管理布局、地图、报表、文件夹连接、视图等工程项目。例如,可以更新、修复或替换图层数据源,修改图层的符号系统,甚至自动在线执行共享要托管在组织中的工程项。 以下代码展示了如何更新图层的数据源&…...