鸿蒙ArkTS实战:从零打造智能表达式计算器(附状态管理+路由传参核心实现)
还在为组件状态混乱、页面跳转丢参数而头疼?
这篇博客将揭秘如何用鸿蒙ArkTS打造一个漂亮美观的智能计算器:
✅ 输入完整表达式,秒出结果——字符串切割简单计算
✅ 状态管理黑科技——@Provide/@Consume 实现跨组件实时响应
✅ 路由传参实战——历史记录页面跳转不丢数据,跨页面传参
✅ 代码即设计稿——ArkTS声明式UI开发,代码比PPT更直观
快捷跳转到想看的地方
- 一、项目展示
- 二、技术栈讲解
- 三、项目结构说明
- 四、核心代码实现
- 1. `Index.ets`父组件总布局查看
- 2. `navbar.ets`实现
- 3. `listView.ets` 展示区的实现
- 4. `buttonView.ets` 按钮区的代码说明
- 五、点赞收藏支持一下吧,代码源码私信我
一、项目展示
这里展示了计算器的加减乘除取余等基本操作,展示了历史记录功能,展示了帮助弹窗

二、技术栈讲解
- 使用arkUI通用组件开发
- 自定义弹窗的实现
- 使用@State,@Link, @Provide, @Consume进行状态管理
- 使用router实现路由跳转以及参数携带
- 使用分模块化结构高效开发
三、项目结构说明
src/ //存放所有与项目逻辑相关的代码文件
├── main/ //包含应用程序的核心模块和组件。
│ ├── ets/ //用于存放与 ArkTS(或类似框架)相关的代码。
│ │ ├── common/ //存放可复用的工具类、辅助函数等。
│ │ ├── data/ //存放数据,这里的data层是不必要的,由于组件数据较多。写在文件里有点乱,这里分了一层
│ │ ├── entryability/ //存放与应用入口相关的逻辑,例如启动时的初始化逻辑。
│ │ ├── entrybackupability/ //存放备用入口逻辑,可能用于异常情况下的备份入口。
│ │ ├── views/ //存放页面中的组件
│ │ ├── pages/ //存放各个页面的逻辑、UI 组件等。
│ │ └── util/ //存放通用工具函数、辅助方法等。
│ └── module.json5 //项目配置文件
└── resources/ //存放静态资源文件,如图片、字体、样式文件等。
四、核心代码实现
1. Index.ets父组件总布局查看
import buttonView from '../views/buttonView'
import navbar from '../views/navbar'
import resultView from '../views/resultView'@Entry
@Component
struct Index {@State calculatorResultText: string = "" //存储打印在结果区的最终结果@State res: number = 0 //存储计算器内部逻辑计算的值@Provide list: string[] = [] // 存储历史记录数组build() {Scroll(){Column(){navbar() // 导航栏resultView({calculatorResultText: this.calculatorResultText, res: this.res}) // 结果打印区buttonView({calculatorResultText: this.calculatorResultText, res: this.res}) // 按钮控制区}}.scrollBar(BarState.Off).expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])//控制模拟器展示安全区为全屏展示.backgroundColor('#1C2220').width('100%').height('100%')}
}
2. navbar.ets实现
// navbar.ets
import app from '@system.app';@Component
export default struct navbar {//定义两个弹窗控制器,来控制弹窗的行为dialogController: CustomDialogController = new CustomDialogController({builder: CustomDialogExample(),})controller: CustomDialogController = new CustomDialogController({builder: CustomDialogExample2({}),})build() {Row(){// 软件logo和名字Row(){Image($r('app.media.calculator')).width(20).margin({left: 20,right: 20})Text('小东计算器').fontColor('#DEDFDF')}// 软件的一些系统功能Row({space: 10}){Text("帮助").fontColor('#DEDFDF').onClick(() => {//触发弹窗this.dialogController.open()})Text("设置").fontColor('#DEDFDF').onClick(() => {//触发弹窗2this.controller.open()})Text("退出").fontColor('#DEDFDF').onClick(() => {app.terminate()})}.margin({right: 20})}.width('100%').justifyContent(FlexAlign.SpaceBetween)}
}//自定义弹窗
@CustomDialog
struct CustomDialogExample {controller: CustomDialogController = new CustomDialogController({builder: CustomDialogExample({}),})//小东计算器的帮助文档build() {Column() {// 标题Text('小东计算器使用帮助').fontSize(24).fontWeight(FontWeight.Bold).margin({ bottom: 16 }).fontColor($r('app.string.calculator_text_color'))// 帮助内容Text('本计算器支持四则运算(+-×÷),输入数字后点击运算符继续计算,按等号(=)显示结果。\n\n'+ '特殊功能:\n'+ '• CE:清除当前输入\n'+ '• C:完全重置计算器\n'+ '• DE:删除最后一位数字\n'+ '• 小数点:点击 . 输入小数部分').fontSize(16).lineHeight(24).fontColor($r('app.string.calculator_text_color'))}.justifyContent(FlexAlign.Center).padding(20).width('100%').backgroundColor($r('app.string.calculator_bk_color'))}
}@CustomDialog
struct CustomDialogExample2 {controller: CustomDialogController = new CustomDialogController({builder: CustomDialogExample2({}),})//设置build() {Column() {//日间模式和夜间模式切换按钮Row() {Text('日间模式').fontColor($r('app.string.calculator_text_color'))Toggle({ type: ToggleType.Switch, isOn: true })}}.justifyContent(FlexAlign.Center).padding(20).width('100%').backgroundColor($r('app.string.calculator_bk_color'))}
}
3. listView.ets 展示区的实现
/*** 计算器结果视图组件* * @Component 声明为可复用的自定义组件* * @State isUnFold - 控制模式选择下拉框的展开状态* @State calculatorState - 当前计算器模式(标准/科学)* @Link calculatorResultText - 双向绑定的计算结果文本* @Link res - 双向绑定的计算结果数值* @Consume list - 消费上下文中的历史记录列表* @State isHover - 按钮悬停状态标识* @State m - M系列功能按钮的标签数组*/
@Component
export default struct resultView {// ... 状态变量声明保持不变build() {Column() {/* 顶部操作栏 - 包含模式切换按钮和历史记录入口 */Row(){// 左侧操作区:模式切换按钮组Row(){// 模式展开/收起触发器Image($r('app.media.ic_grid_setting')).onClick(() => { this.isUnFold = !this.isUnFold })// 当前模式显示文本Text(this.calculatorState).margin({left: 20, right: 20})// 辅助功能按钮Image($r('app.media.ic_global_menu'))}// 右侧操作区:历史记录入口Row(){Image($r('app.media.ic_time')).onClick(() => { router.pushUrl({ url: 'pages/AfterCheck' }) })}}.justifyContent(FlexAlign.SpaceBetween)/* 结果展示区域 - 包含模式选择下拉框和计算结果显示 */Stack(){// 模式选择下拉框(条件渲染)if (this.isUnFold){Column({space: 10}) {// 标准模式选项Text("标准计算器").onClick(() => {this.calculatorState = '标准'this.isUnFold = false})// 科学模式选项(未实现)Text("科学计算器").onClick(() => {this.calculatorState = '科学'this.isUnFold = false})}}// 计算结果显示区域Row() {Column() {Text(`${this.calculatorResultText}`) // 显示计算结果文本.textAlign(TextAlign.End) // 右对齐显示}}}.alignContent(Alignment.TopStart)/* M系列功能按钮区域 - 当前为占位实现 */Row() {ForEach(this.m, (item: string) =>{Column() {Button(item).hoverEffect(HoverEffect.Scale) // 悬停缩放效果.onHover((hovered: boolean) => {this.isHover = hovered // 更新悬停状态})}})}}.padding(10)}
}
4. buttonView.ets 按钮区的代码说明
/*** 计算器按钮视图组件* @Component 标记为可复用的UI组件* @struct 定义组件结构* * @State button - 按钮标签数组,包含计算器所有操作符和数字:* '%' 取模, 'CE' 清空输入, 'C' 清空, 'DE' 删除字符,* 数字0-9, 运算符x-乘、-减、+加、÷除, '=' 计算结果* @State isHover - 按钮悬停状态标识* @Link res - 双向绑定的计算结果数值* @Link calculatorResultText - 双向绑定的计算表达式文本* @Consume list - 消费的历史记录列表,用于存储计算记录*/
@Component
export default struct buttonView {@State button: string[] = ['%','CE','C','DE', '7', '8', '9', 'x', '4', '5', '6', '-', '1', '2', '3', '+', '0', '.', '÷','=']@State isHover:boolean = false@Link res: number@Link calculatorResultText: string;@Consume list: string[]/*** 构建计算器界面布局* 使用网格布局创建按钮矩阵,处理按钮交互事件*/build() {Column() {Grid(){// 动态生成计算器按钮矩阵ForEach(this.button, (item: string, index: number) =>{GridItem() {Button(item).fontSize(24).fontColor($r('app.string.calculator_text_color')).backgroundColor(this.isHover? Color.Gray : $r('app.string.calculator_bk_color')).hoverEffect(HoverEffect.Scale).onHover((hover: boolean) => {this.isHover = hover; // 更新全局悬停状态}).onClick(() => {// 处理不同按钮的点击逻辑if (item === '=') {this.calculator(this.calculatorResultText)}if(item === 'CE'){this.calculatorResultText = ''}if(item === 'C'){this.calculatorResultText = ""}if(item === 'DE'){this.calculatorResultText = this.calculatorResultText.slice(0, -1)}// 处理数字和运算符输入if(item !== 'CE' && item !== 'C' && item !== 'DE' && item !== '='){this.calculatorResultText += item}})}.width(80).height(80)})}.width('100%').rowsTemplate('1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr') // 8行等分布局.columnsTemplate('1fr 1fr 1fr 1fr') // 4列等分布局}.width('100%')}/*** 计算器核心逻辑处理函数* @param text - 需要计算的表达式字符串* 功能:解析计算表达式,执行运算,更新结果和历史记录*/calculator(text: string) {let exe: string = text;// 解析表达式为操作数和运算符数组let arr: string[] = []for (let i = 0; i < text.length; i++) {if (text[i] === '+' || text[i] === '-' || text[i] === 'x' || text[i] === '÷' || text[i] === '%') {arr.push(text.slice(0, i))arr.push(text[i])text = text.slice(i + 1)i = 0}}// 根据运算符执行对应计算if(arr[1] === '+'){this.res = Number(arr[0]) + Number(text)}else if(arr[1] === '-'){this.res = Number(arr[0]) - Number(text)}else if(arr[1] === 'x'){this.res = Number(arr[0]) * Number(text)}else if(arr[1] === '÷'){this.res = Number(arr[0]) / Number(text)}else if(arr[1] === '%'){this.res = Number(arr[0]) % Number(text)}// 记录完整计算表达式并更新结果exe += '=' + this.resthis.calculatorResultText = this.res.toString()this.list.push(exe) // 添加历史记录}
}
五、点赞收藏支持一下吧,代码源码私信我
相关文章:
鸿蒙ArkTS实战:从零打造智能表达式计算器(附状态管理+路由传参核心实现)
还在为组件状态混乱、页面跳转丢参数而头疼? 这篇博客将揭秘如何用鸿蒙ArkTS打造一个漂亮美观的智能计算器: ✅ 输入完整表达式,秒出结果——字符串切割简单计算 ✅ 状态管理黑科技——Provide/Consume 实现跨组件实时响应 ✅ 路由传参实战—…...
【58】编程技巧:单片机编程命名规范
【58】编程技巧:单片机编程命名规范 引言 在大型嵌入式项目开发中,变量和常量的命名混乱会导致代码难以维护。本文系统阐述变量、常量、指针、结构体等命名规范,通过统一规则提升代码可读性与协作效率。目标是帮助开发者建立清晰的命名习惯&…...
Windows 部署项目 apache + mod_wsgi,nginx + waitress
文章目录 1、apache mod_wsgi,nginx waitress两种部署方式的区别2、以nginx waitress为例 有些项目必须部署在windows上,有IIS wfastcgi、apache mod_wsgi,nginx waitress部署方式 1、apache mod_wsgi,nginx waitress两种…...
车辆视频检测器linux版对于密码中包含敏感字符的处理方法
由于密码中含有敏感字符,导致前端页面异常,图标变灰,坐标拾取打不开图像等,主要原因是:密码比较前后不一致,左边是Abc_110,右边是:Abc_110%2B,对于此问题,特别…...
Java服务端开发基石:深入理解Spring IoC与依赖注入 (DI)
今天,我们从现代Java开发,尤其是企业级应用中,几乎无处不在的Spring框架的核心概念开始:控制反转(Inversion of Control, IoC) 与 依赖注入(Dependency Injection, DI)。理解它们&am…...
【人工智能】大语言模型多义词解析技术揭秘——以“项目“歧义消解为例
今天田辛老师和小伙伴探讨了一个有趣的多义词问题, 在人工智能技术日新月异的今天,大语言模型(LLM)对自然语言的理解能力已经达到令人惊叹的水平。大模型到底是如何去区分多义词的? 比如:当用户提到"…...
贪心算法(17)(java)可被三整除的最大整数和
给你一个整数数组 nums,请你找出并返回能被三整除的元素 最大和。 示例 1: 输入:nums [3,6,5,1,8] 输出:18 解释:选出数字 3, 6, 1 和 8,它们的和是 18(可被 3 整除的最大和)。 …...
qq邮箱群发程序
1.界面设计 1.1 环境配置 在外部工具位置进行配置 1.2 UI界面设计 1.2.1 进入QT的UI设计界面 在pycharm中按顺序点击,进入UI编辑界面: 点击第三步后进入QT的UI设计界面,通过点击按钮进行界面设计,设计后进行保存到当前Pycharm…...
K8S学习之基础七十九:关闭istio功能
关闭istio功能 kubectl get ns --show-labels kubectl label ns default istio-injection-有istio-injectionenabled的命名空间,pod都会开启istio功能 反之,如果要开启istio,在对应命名空间打上该标签即可...
上门预约洗鞋店小程序都具备哪些功能?
现在大家对洗鞋子的清洗条件越来越高,在家里不想去,那就要拿去洗鞋店去洗。如果有的客户没时间去洗鞋店,这个时候,有个洗鞋店小程序就可以进行上门取件,帮助没时间的客户去取需要清洗的鞋子,这样岂不是既帮…...
在Ubuntu 22.04上配置【C/C++编译环境】
在Ubuntu 22.04上配置C/C编译环境 如果你想在Ubuntu 22.04上编译和运行C或C程序,首先需要安装一个合适的编译器和相关工具。本文将为你提供详细的安装建议和操作步骤,帮助你快速搭建开发环境。 准备工作 在开始之前,确保你的系统可以通过终…...
蓝桥杯——走迷宫(Java-BFS)
这是一个经典的BFS算法 1. BFS算法保证最短路径 核心机制:广度优先搜索按层遍历所有可能的路径,首次到达终点的路径长度即为最短步数。这是BFS的核心优势。队列的作用:通过队列按先进先出的顺序处理节点,确保每一步探索的都是当…...
Spring MVC与Spring Boot文件上传配置差异对比及文件上传关键类详细说明与对比
一、Spring MVC与Spring Boot文件上传配置差异对比 1. 配置方式差异 框架配置方式依赖管理自动配置Spring MVC需手动配置MultipartResolver(如StandardServletMultipartResolver)需自行引入commons-fileupload等依赖无,默认不启用文件上传支…...
LLM 的model.generate() 参数说明
LLM 的model.generate() 参数说明 目录 LLM 的model.generate() 参数说明生成长度控制参数采样策略参数重复惩罚参数束搜索参数其他参数model.generate() 方法是 Hugging Face Transformers 库中用于文本生成的核心方法,它有众多参数可用于控制生成过程 生成长度控制参数 min…...
下载firefox.tar.xz后如何将其加入到Gnome启动器
起因:近期(2025-04-07)发现firefox公布了130.0 版本,可以对pdf文档进行签名了,想试一下,所以卸载了我的Debian12上的firefox-esr,直接下载了新版本的tar.xz 包。 经过一番摸索,实现了将其加入Gn…...
Flutter性能优化终极指南:从JIT到AOT的深度调优
一、Impeller渲染引擎调优策略 1.1 JIT预热智能预编译 // 配置Impeller预编译策略 void configureImpeller() {ImpellerEngine.precacheShaders(shaders: [lib/shaders/skinned_mesh.vert,lib/shaders/particle_system.frag],warmupFrames: 30, // 首屏渲染前预编译帧数cach…...
加密≠安全:文件夹密码遗忘背后的数据丢失风险与应对
在数字化时代,保护个人隐私和数据安全变得尤为重要。许多人选择对重要文件夹进行加密,以防止未经授权的访问。然而,一个常见且令人头疼的问题也随之而来——文件夹加密密码遗忘。当你突然发现自己无法访问那些加密的文件夹时,那种…...
实习技能记录【2】-----LVGL[基本概念]
LVGL主要概念 1. Screen (屏幕): 概念: 屏幕是 LVGL 应用程序中的顶层容器。它是用户界面的根对象,所有的可见 UI 元素最终都会添加到某个屏幕上(通常是活动屏幕)。 功能: 作为其他 UI 元素的父对象。 可以拥有自己的背景颜色、背景图片等样…...
【操作系统(Linux)】——通过案例学习父子进程的线程异步性
本篇旨在通过几个案例来学习父子进程的线程异步性 一、父进程与子进程 我们将要做的: 创建父子进程,观察父子进程执行的顺序,了解进程执行的异步行为 源代码: #include <stdio.h> #include <sys/types.h> #include…...
Go 语言范围 (Range)
Go 语言范围 (Range) Go 语言是一种静态强类型、编译型、并发型编程语言,由 Google 开发。它的简洁性和高效性使其成为众多开发者的首选。在 Go 语言中,range 是一个非常有用的关键字,用于遍历数组、切片、字符串以及通道(channe…...
【开源宝藏】30天学会CSS - DAY12 第十二课 从左向右填充的文字标题动画
用伪元素搞定文字填充动效:一行 JS 不写,效果炸裂 你是否曾经在设计页面标题时,觉得纯文字太寡淡?或者想做一个有动感的文字特效,但又不想引入 JS 甚至 SVG? 在这篇文章中,我们将通过 一段不到…...
nginx或tengine服务器,配置HTTPS下使用WebSocket的线上环境实践!
问题描述: HTTPS 下发起WS连接,连接失败,Chrom 浏览器报错。 socket.js:19 Mixed Content: The page at https://app.XXX.com was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint ws://172.16.10.80:903…...
WSA(Windows 安卓子系统)过检测教程
windows安卓子系统WSA的root和magisk的安装教程 安卓子系统WSLWSA的rootmagisk安装 WSA(Windows 安卓子系统)过检测的方法与思路 一、引言 Windows 安卓子系统(WSA)为 Windows 用户提供了在电脑上运行安卓应用的便利。然而&…...
蓝桥杯 B3620 x 进制转 10 进制
题目描述 给一个小整数 x 和一个 x 进制的数 S。将 S 转为 10 进制数。对于超过十进制的数码,用 A,B,… 表示。 输入格式 第一行一个整数 x; 第二行一个字符串 S。 输出格式 输出仅包含一个整数,表示答案。 输入输出样例 …...
【Oracle篇】跨字符集迁移:基于数据泵的ZHS16GBK转AL32UTF8全流程迁移
💫《博主主页》:奈斯DB-CSDN博客 🔥《擅长领域》:擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控;并对SQLserver、NoSQL(MongoDB)有了解 💖如果觉得文章对你有所帮…...
Qt子模块的功能介绍
一、Qt 主要子模块的功能介绍 1. 核心模块 模块名称功能描述QtCore核心非GUI功能(信号槽、线程、文件IO、容器类、JSON/XML处理等)QtGui基础图形绘制(窗口系统集成、OpenGL抽象、图像处理、字体管理等)QtConcurrent高级多线程API(并行计算框架,如QtConcurrent::run)QtN…...
FRP练手:hello,world实现
方案一:使用 Flask(推荐) from flask import Flaskapp Flask(__name__)app.route(/) def hello_world():return "你好啊世界"if __name__ __main__:# 监听所有网络接口(0.0.0.0),端口 3344app.…...
《深入探秘:分布式软总线自发现、自组网技术原理》
在当今数字化浪潮中,分布式系统的发展日新月异,而分布式软总线作为实现设备高效互联的关键技术,其自发现与自组网功能宛如打开智能世界大门的钥匙,为多设备协同工作奠定了坚实基础。 分布式软总线的重要地位 分布式软总线是构建…...
西门子S7-1200PLC 工艺指令PID_Temp进行控温
1.硬件需求: 西门子PLC:CPU 1215C DC/DC/DC PLC模块:SM 1231 TC模块 个人电脑:已安装TIA Portal V17软件 加热套:带加热电源线以及K型热电偶插头 固态继电器:恩爵 RT-SSK4A2032-08S-F 其他࿱…...
提升Windows安全的一些措施
由简单到复杂,仅供参考 一、杀毒软件: 1、杀毒能力: https://haokan.hao123.com/v?vid3883775443252827335&pdhaokan_share 2、使用注意: 一台主机只安装一个杀毒软件就可以了 杀毒软件会误报,造成正常文件…...
