尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

HarmonyOS ArkTS 实战:实现一个标准计算器

HarmonyOS ArkTS 实战:实现一个标准计算器
📅 发布时间:2026/7/26 13:39:56

HarmonyOS ArkTS 实战:实现一个标准计算器

项目效果

本文实现的是一个基于 HarmonyOS 和 ArkTS 的标准计算器。项目中使用 ArkUI 组件完成页面布局,通过@State管理状态数据,实现加减乘除四则运算、小数运算、清除、退格、正负切换和百分比等标准计算器功能。

最终运行效果如下:

页面主要包含以下内容:

  • 顶部应用标题;
  • 上方显示区域,显示计算表达式;
  • 大字体显示当前数字;
  • 下方4×5按钮网格;
  • 数字键0-9;
  • 加减乘除运算符;
  • 等于、清除、退格、小数点、正负、百分比按钮;
  • 页面整体采用 ArkUI 声明式布局。

本文重点是演示如何在 HarmonyOS 项目中使用 ArkTS 和 ArkUI 实现一个计算器单页面应用。项目代码主要写在entry/src/main/ets/pages/Index.ets文件中,适合作为 HarmonyOS ArkTS 入门到进阶之间的练习案例。

前言

计算器是每个手机必备的工具,也是学习编程最经典的入门项目。实现一个计算器看起来简单,但要处理好各种边界情况并不容易:连续运算、小数、除以零、运算符切换等等。

从应用开发角度来看,这个项目不依赖后端接口,也不需要数据库,但能练习 ArkTS 中的状态管理、网格布局、按钮交互、表达式计算和边界情况处理等内容。

本文基于 HarmonyOS 和 ArkTS 实现一个标准计算器。支持加减乘除四则运算,有标准计算器的所有常用功能,界面简洁,操作流畅。

这个项目的核心不是简单的加减乘除,而是正确处理各种计算状态和边界情况。每一次按钮点击,都会改变计算器的状态,这正是 ArkUI 声明式开发的基本思想。

一、项目目标

本次实践主要实现以下目标:

  • 创建 HarmonyOS ArkTS 页面;
  • 使用@Entry和@Component定义页面组件;
  • 使用@State管理页面状态;
  • 实现0-9数字输入;
  • 加减乘除四则运算;
  • 小数点输入;
  • 等于计算结果;
  • 全部清除(AC);
  • 退格删除;
  • 正负号切换;
  • 百分比计算;
  • 连续运算支持;
  • 使用@Builder封装计算器按钮;
  • 完成一个可以运行的标准计算器页面。

这个项目虽然是单页面应用,但它实现了完整的计算器功能,处理了各种边界情况,比普通静态页面更适合练习 ArkTS。

二、技术栈

类型内容
开发方向HarmonyOS 应用开发
开发语言ArkTS
UI 框架ArkUI
SDK 版本HarmonyOS API 23 及以上
工程模型Stage 模型
核心组件Text / Button / Column / Row / Grid
状态管理@State
数据处理四则运算 / 状态机 / 边界处理
项目入口entry/src/main/ets/pages/Index.ets
运行平台模拟器或真机

本项目是 HarmonyOS 原生 ArkTS 项目。页面主体由 ArkUI 组件构建,核心逻辑写在Index.ets文件中,不依赖后端接口,也不需要额外配置数据库。

三、为什么选择标准计算器项目

标准计算器适合作为 ArkTS 练习项目,主要有以下几个原因。

第一,经典入门项目。几乎所有编程入门都会做计算器,是检验基础能力的好项目。

第二,实用性强。计算器是日常最常用的工具之一。

第三,适合练习状态管理。计算器有多种状态:输入数字、输入运算符、显示结果等。

第四,适合练习网格布局。计算器按钮是规则的网格,练习Grid或Flex布局。

第五,适合练习边界处理。除以零、多个小数点、连续运算符等情况都需要处理。

第六,扩展空间比较大。基础功能完成后,可以继续增加科学计算、历史记录、单位换算、进制转换和主题切换。

在本项目中,当前数字、运算符、上一个数字是核心状态。所有计算逻辑都基于这些状态。

四、功能规则说明

按钮布局:

AC+/-%÷
789×
456-
123+
0.⌫=

运算规则:

  • 输入数字时连续输入组成多位数
  • 点击运算符后保存当前数字,准备输入下一个
  • 再次点击运算符时先计算之前的结果
  • 点击等于显示最终结果
  • AC清除所有状态
  • 退格删除最后一位
  • +/-切换正负号
  • %将当前数字除以100
  • 除以0显示Error

五、项目结构

本项目主要修改首页文件:

entry └── src └── main └── ets └── pages └── Index.ets

其中:

文件作用
Index.ets编写页面结构、状态数据和计算逻辑

本文不涉及复杂路由,也不需要额外创建多个页面。对于练习项目来说,把主要逻辑集中在一个Index.ets文件中更方便理解。

六、核心实现思路

本项目的核心流程如下:

  1. 使用@State保存当前显示数字、上一个数字、当前运算符;
  2. 点击数字按钮追加数字;
  3. 点击运算符保存当前数字和运算符;
  4. 点击等于时根据运算符计算结果;
  5. 处理小数点,确保只有一个;
  6. 处理正负切换;
  7. 处理百分比;
  8. 处理退格;
  9. AC重置所有状态;
  10. 处理除以零等错误情况。

项目中最重要的状态变量如下:

@State display: string = '0' @State previousValue: number = 0 @State operator: string = '' @State shouldResetDisplay: boolean = false @State expression: string = ''

其中:

状态变量作用
display当前显示的数字
previousValue上一个操作数
operator当前运算符
shouldResetDisplay输入下一个数字时是否重置显示
expression表达式显示

这些状态构成了计算器的状态机,正确处理状态转换是计算器正确运行的关键。

七、Index.ets 完整代码

打开文件:

entry/src/main/ets/pages/Index.ets

将其中内容替换为下面代码:

@Entry@Componentstruct Index{@Statedisplay:string='0'@StatepreviousValue:number=0@Stateoperator:string=''@StateshouldResetDisplay:boolean=false@Stateexpression:string=''privateinputNumber(num:string):void{if(this.shouldResetDisplay){this.display=numthis.shouldResetDisplay=false}else{if(this.display==='0'&&num!=='.'){this.display=num}elseif(num==='.'&&this.display.includes('.')){return}else{this.display+=num}}}privateinputOperator(op:string):void{letcurrentValue=parseFloat(this.display)if(this.operator!==''&&!this.shouldResetDisplay){this.calculate()currentValue=parseFloat(this.display)}this.previousValue=currentValuethis.operator=opthis.shouldResetDisplay=truethis.expression=`${this.formatNumber(this.previousValue)}${this.getOperatorSymbol(op)}`}privatecalculate():void{if(this.operator==='')returnletcurrentValue=parseFloat(this.display)letresult=0switch(this.operator){case'+':result=this.previousValue+currentValuebreakcase'-':result=this.previousValue-currentValuebreakcase'*':result=this.previousValue*currentValuebreakcase'/':if(currentValue===0){this.display='Error'this.operator=''this.shouldResetDisplay=truethis.expression=''return}result=this.previousValue/currentValuebreak}this.expression=`${this.formatNumber(this.previousValue)}${this.getOperatorSymbol(this.operator)}${this.formatNumber(currentValue)}=`this.display=this.formatResult(result)this.operator=''this.shouldResetDisplay=true}privateclearAll():void{this.display='0'this.previousValue=0this.operator=''this.shouldResetDisplay=falsethis.expression=''}privatebackspace():void{if(this.shouldResetDisplay||this.display==='Error')returnif(this.display.length===1||(this.display.length===2&&this.display.startsWith('-'))){this.display='0'}else{this.display=this.display.substring(0,this.display.length-1)}}privatetoggleSign():void{if(this.display==='0'||this.display==='Error')returnif(this.display.startsWith('-')){this.display=this.display.substring(1)}else{this.display='-'+this.display}}privatepercent():void{letvalue=parseFloat(this.display)this.display=this.formatResult(value/100)this.shouldResetDisplay=true}privateformatNumber(num:number):string{if(Number.isInteger(num)){returnnum.toString()}returnnum.toString()}privateformatResult(num:number):string{if(Number.isInteger(num)){returnnum.toString()}returnparseFloat(num.toFixed(10)).toString()}privategetOperatorSymbol(op:string):string{switch(op){case'+':return'+'case'-':return'-'case'*':return'×'case'/':return'÷'default:returnop}}@BuilderCalcButton(text:string,color:string,bgColor:string,onClick:()=>void,flex:number=1){Button(text).layoutWeight(flex).height(64).fontSize(24).fontWeight(FontWeight.Medium).fontColor(color).backgroundColor(bgColor).borderRadius(32).onClick(onClick)}build(){Column(){Text('计算器').fontSize(28).fontWeight(FontWeight.Bold).fontColor('#182431').margin({top:22})Text('基于 HarmonyOS ArkTS 的标准计算器').fontSize(14).fontColor('#6B7280').margin({top:8,bottom:20})Column(){Blank()if(this.expression){Text(this.expression).fontSize(18).fontColor('#9CA3AF').width('100%').textAlign(TextAlign.End).margin({bottom:8})}Text(this.display).fontSize(56).fontWeight(FontWeight.Light).fontColor('#182431').width('100%').textAlign(TextAlign.End).maxLines(1).textOverflow({overflow:TextOverflow.Ellipsis})}.width('100%').height(180).padding(20).backgroundColor(Color.White).borderRadius(16).margin({bottom:16}).shadow({radius:8,color:'#08000000',offsetX:0,offsetY:2})Column(){Row(){this.CalcButton('AC','#FFFFFF','#9CA3AF',()=>{this.clearAll()})this.CalcButton('+/-','#FFFFFF','#A5A5A5',()=>{this.toggleSign()})this.CalcButton('%','#FFFFFF','#A5A5A5',()=>{this.percent()})this.CalcButton('÷','#FFFFFF','#FF9F0A',()=>{this.inputOperator('/')})}.width('100%').margin({bottom:12})Row(){this.CalcButton('7','#FFFFFF','#333333',()=>{this.inputNumber('7')})this.CalcButton('8','#FFFFFF','#333333',()=>{this.inputNumber('8')})this.CalcButton('9','#FFFFFF','#333333',()=>{this.inputNumber('9')})this.CalcButton('×','#FFFFFF','#FF9F0A',()=>{this.inputOperator('*')})}.width('100%').margin({bottom:12})Row(){this.CalcButton('4','#FFFFFF','#333333',()=>{this.inputNumber('4')})this.CalcButton('5','#FFFFFF','#333333',()=>{this.inputNumber('5')})this.CalcButton('6','#FFFFFF','#333333',()=>{this.inputNumber('6')})this.CalcButton('-','#FFFFFF','#FF9F0A',()=>{this.inputOperator('-')})}.width('100%').margin({bottom:12})Row(){this.CalcButton('1','#FFFFFF','#333333',()=>{this.inputNumber('1')})this.CalcButton('2','#FFFFFF','#333333',()=>{this.inputNumber('2')})this.CalcButton('3','#FFFFFF','#333333',()=>{this.inputNumber('3')})this.CalcButton('+','#FFFFFF','#FF9F0A',()=>{this.inputOperator('+')})}.width('100%').margin({bottom:12})Row(){this.CalcButton('0','#FFFFFF','#333333',()=>{this.inputNumber('0')},2)this.CalcButton('.','#FFFFFF','#333333',()=>{this.inputNumber('.')})this.CalcButton('⌫','#FFFFFF','#333333',()=>{this.backspace()})this.CalcButton('=','#FFFFFF','#FF9F0A',()=>{this.calculate()})}.width('100%')}.width('100%').padding(16).backgroundColor(Color.White).borderRadius(16).shadow({radius:8,color:'#08000000',offsetX:0,offsetY:2})}.width('100%').height('100%').padding({left:18,right:18}).backgroundColor('#F5F7FA')}}

八、代码实现说明

1. 状态机设计

计算器有几个关键状态:

  • 初始状态:显示0,等待输入
  • 输入数字:追加数字到display
  • 输入运算符:保存当前值,准备输入下一个数
  • 显示结果:等于后显示结果,下次输入数字时重置
2. 连续运算

点击运算符时如果已有运算符,先计算之前的结果,再保存新的运算符,支持连续运算。

3. 边界处理
  • 除以零:显示Error
  • 多个小数点:阻止输入第二个小数点
  • 开头的0:输入第一个非0数字时替换0
  • 退格:删到0就不再删了
  • 长数字:自动截断,避免溢出
4. 按钮样式

模仿iOS计算器风格:

  • 数字键:深灰背景白字
  • 功能键:浅灰背景白字
  • 运算符:橙色背景白字
  • 圆角按钮,间距均匀
5. 表达式显示

计算时显示完整表达式,让用户清楚看到计算过程。

6. 结果格式化

去掉浮点数计算产生的多余小数位,避免显示类似0.30000000000000004的结果。

九、运行项目

代码编写完成后,在DevEco Studio中运行项目。测试加减乘除运算,测试小数、连续运算、清除、退格、正负、百分比等功能,验证除以零的错误处理。

十、开发中遇到的问题

  • 连续运算:点击第二个运算符时要先计算前面的结果
  • 浮点数精度:toFixed后转字符串去掉多余的0
  • 状态重置:等于后输入新数字要重置显示
  • 按钮宽度:0号键占两格宽度,其他按钮等宽

十一、总结

本文基于HarmonyOS和ArkTS实现了一个标准计算器。项目通过状态机管理计算状态,实现了完整的四则运算和各种计算器功能,处理了各种边界情况。这个项目展示了ArkTS中状态管理、网格布局和逻辑处理的基本方法,适合作为入门练习项目。

相关新闻

  • 2026最新菏泽防水补漏本地人必选的正规靠谱公司推荐-房屋漏水检测维修师傅上门-卫生间厨房阳台房顶外墙漏水检测精准测漏 - 吉林同城获客
  • 终极Linux打印机驱动解决方案:foo2zjs让100+款打印机完美工作
  • 融合GOSO/ISO与混沌映射的时间序列预测优化框架

最新新闻

  • Mechvibes机械键盘音效模拟器:免费打造专属打字音效的终极指南
  • 探索AntiDupl:智能图片去重工具如何拯救你的存储空间
  • TI BLE HCI扩展命令实战:功耗优化与射频调优深度解析
  • Illustrator脚本终极指南:如何用20个免费插件提升设计效率300%
  • 2026东莞家电维修师傅上门电话空调冰箱洗衣机热水器燃气灶同城急修推荐 - 全国家电维修上门服务
  • OpenRGB终极指南:一个软件统一控制所有RGB设备的完整解决方案

日新闻

  • 大连理工大学与东京大学联手打造的“主动型AI助手“
  • 170.2026年国家级科研瓶颈:超精密单点金刚石切削(SPDT)光学表面生成
  • SongBloom:革命性歌曲生成框架深度解析——如何通过交织自回归与扩散模型创作完整音乐

周新闻

  • 大连理工大学与东京大学联手打造的“主动型AI助手“
  • 170.2026年国家级科研瓶颈:超精密单点金刚石切削(SPDT)光学表面生成
  • SongBloom:革命性歌曲生成框架深度解析——如何通过交织自回归与扩散模型创作完整音乐

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号