【HarmonyOS——ArkTS语言】计算器的实现【合集】

简介: 【ArkTS语言-HarmonyOS】计算器的实现【合集】组件,点击等号后计算函数高效解析表达式并给出准确结果,达成核心功能要求。错误提示不够详尽,难以助力用户快速定位输入错误;响应式设计不足,在不同屏幕规格下适配性差。总体而言,本次实验已成功构建起基本功能框架,后续将针对上述问题深入探究优化方案,不断打磨细节,在完善计算器功能与提升用户体验的道路上持续精进,进而提升自身编程与应用开发的综合能力水平。利用按钮组件顺利完成布局设计,数字、运算符及功能按钮排列有序,操作逻辑清晰直观。

目录

😋环境配置:华为HarmonyOS开发者

🎯学习小目标:

📺演示效果:

📖实验步骤及方法:

1. 在index.ets文件中通过 @Extend(Button) 装饰器扩展Button 组件设置按钮样式函数myButton

2. 设置运算符枚举类型 Operator

3. 设置获取运算符优先级的函数 getOperatorPrecedence

4.设置计算表达式结果的函数 calculateResult

5.设置主界面组件 Index

6.模拟机运行测试

👋实验小结


😋环境配置:华为HarmonyOS开发者

🎯学习小目标:

  1. 创建一个工程,在index.ets文件中进行编辑
  2. 使用按钮组件设计计算器的布局
  3. 点击按钮后将计算过程显示在Text组件中
  4. 点击等号显示计算结果

📺演示效果:

image.gif 编辑 image.gif 编辑 image.gif 编辑

图1 预览器演示效果

📖实验步骤及方法:

1. 在index.ets文件中通过 @Extend(Button) 装饰器扩展Button 组件设置按钮样式函数myButton

@Extend(Button)
function myButton() {
.type(ButtonType.Normal)
.width("270px")
.height("270px")
.backgroundColor(Color.Black)
.border({ color: Color.White, style: BorderStyle.Solid, width: 2 })
.fontSize(40)
.fontColor(Color.White)
.fontWeight(800)
.borderRadius(0)
}

image.gif

2. 设置运算符枚举类型 Operator

enum Operator {
  PLUS = '+',
  MINUS = '-',
  TIMES = '*',
  DIVIDE = '/'
}

image.gif

3. 设置获取运算符优先级的函数 getOperatorPrecedence

function getOperatorPrecedence(operator: string): number {
  switch (operator) {
    case Operator.PLUS:
    case Operator.MINUS:
      return 1;
    case Operator.TIMES:
    case Operator.DIVIDE:
      return 2;
    default:
      throw new Error("Invalid operator: " + operator);
  }
}

image.gif

4.设置计算表达式结果的函数 calculateResult

function calculateResult(expression: string): number {
  // 去除表达式两端可能存在的空白字符
  expression = expression.trim();
  // 使用两个栈,一个用于存储操作数,一个用于存储运算符
  let operandStack: number[] = [];
  let operatorStack: string[] = [];
  // 用于临时存储数字字符组成的字符串,以便转换为数字
  let tempNumber = "";
  for (let i = 0; i < expression.length; i++) {
    let char = expression[i];
    if (char >= '0' && char <= '9' || char === '.') {
      // 如果是数字字符或小数点,累加到临时数字字符串中
      tempNumber += char;
    } else if (char === '+' || char === '-' || char === '*' || char === '/') {
      // 如果是运算符
      // 先将之前临时存储的数字转换为实际数字并压入操作数栈
      if (tempNumber!== "") {
        operandStack.push(Number(tempNumber));
        tempNumber = "";
      }
      // 处理运算符栈,按照优先级进行运算
      while (
        operatorStack.length > 0 &&
          getOperatorPrecedence(operatorStack[operatorStack.length - 1]) >= getOperatorPrecedence(char)
      ) {
        let operator = operatorStack.pop();
        let operand2 = operandStack.pop();
        +
        let operand1 = operandStack.pop();
        // 验证弹出的操作数是否有效
        if (Operand1 === undefined || operand2 === undefined) {
          throw new Error("Invalid operation: missing operand(s)");
        }
        if (operator === Operator.PLUS) {
          operandStack.push(Operand1 + operand2);
        } else if (operator === Operator.MINUS) {
          operandStack.push(Operand1 - operand2);
        } else if (operator === Operator.TIMES) {
          operandStack.push(Operand1 * operand2);
        } else if (operator === Operator.DIVIDE) {
          operandStack.push(Operand1 / operand2);
        }
      }
      // 将当前运算符压入运算符栈
      operatorStack.push(char);
    } else if (char === '(') {
      // 如果是左括号,直接压入运算符栈
      operatorStack.push(char);
    } else if (char === ')') {
      // 如果是右括号
      // 先将之前临时存储的数字转换为实际数字并压入操作数栈
      if (tempNumber!== "") {
        operandStack.push(Number(tempNumber));
        tempNumber = "";
      }
      // 处理运算符栈,直到遇到左括号
      while (
        operatorStack.length > 0 &&
          operatorStack[operatorStack.length - 1]!== '(') {
        let operator = operatorStack.pop();
        let operand2 = operandStack.pop();
        let operand1 = operandStack.pop();
        // 验证弹出的操作数是否有效
        if (Operand1 === undefined || operand2 === undefined) {
          throw new Error("Invalid operation: missing operand(s)");
        }
        if (operator === Operator.PLUS) {
          operandStack.push(Operand1 + operand2);
        } else if (operator === Operator.MINUS) {
          operandStack.push(Operand1 - operand2);
        } else if (operator === Operator.TIMES) {
          operandWordStack.push(Operand1 * operand2);
        } else if (operator ==Operator.DIVIDE) {
          operandStack.push(Operand1 / operand2);
        }
      }
      // 弹出左括号
      operatorStack.pop();
    }
  }
  // 处理表达式末尾可能存在的数字
  if (tempNumber!== "") {
    operandStack.push(Number(tempNumber));
  }
  // 处理运算符栈中剩余的运算符
  if (operatorStack.length > 0) {
    let operator = operatorStack.pop();
    let operand2 = operandStack.pop();
    let operand1 = operandStack.pop();
    // 验证弹出的操作数是否有效
    if (Operand1 === undefined || operand2 === undefined) {
      throw new Error("Invalid operation: missing operand(s)");
    }
    if (operator === Operator.PLUS) {
        operandStack.push(Operand1 + operand2);
    } else if (operator === Operator.MINUS) {
        operandStack.push(Operand1 - operand2);
    } else if (operator === Operator.TIMES) {
        operandStack.push(Operand1 * operand2);
    } else if (operator ==Operator.DIVIDE) {
        operandStack.push(Operand1 / operand2);
    }
    }
    // 返回最终的计算结果
    return operandStack[0];
}

image.gif

5.设置主界面组件 Index

@Entry
@Component
struct Index {
  @State result: string = ""
  @State number: number = 0
  build() {
    Column() {
      Row() {
        Text(this.result).fontSize(50)
      }
      Row() {
        Column() {
          Button("7").onClick(() => {
            this.result += "7"
          }).myButton()
        }
        Column() {
          Button("8").onClick(() => {
            this.result += "8"
          }).myButton()
        }
        Column() {
          Button("9").onClick(() => {
            this.result += "9"
          }).myButton()
        }
        Column() {
          Button("+").onClick(() => {
            this.result += "+"
          }).myButton()
        }
      }
      Row() {
        Column() {
          Button("4").onClick(() => {
            this.result += "4"
          }).myButton()
        }
        Column() {
          Button("5").onClick(() => {
            this.result += "5"
          }).myButton()
        }
        Column() {
          Button("6").onClick(() => {
            this.result += "6"
          }).myButton()
        }
        Column() {
          Button("-").onClick(() => {
            this.result += "-"
          }).myButton()
        }
      }
      Row() {
        Column() {
          Button("1").onClick(() => {
            this.result += "1"
          }).myButton()
        }
        Column() {
          Button("2").onClick(() => {
            thisresult += "2"
          }).myButton()
        }
        Column() {
          Button("3").onClick(() => {
            this.result += "3"
          }).myButton()
        }
        Column() {
          Button("*").onClick(() => {
            this.result += "*"
          }).myButton()
        }
      }
      Row() {
        Column() {
          Button("0").onClick(() => {
            this.result += "0"
          }).myButton()
        }
        Column() {
          Button(".").onClick(() => {
            this.result += "."
          }).myButton()
        }
        Column() {
          Button("=").onClick(() => {
            try {
              this.result = calculateResult(this.result).toString();
            } catch (e) {
              this.result = "Error: " + e.message;
            }
          }).myButton()
        }
        Column() {
          Button("/").onClick(() => {
            this.result += "/"
          }).myButton()
        }
      }
      Row() {
        Column() {
          Button("C").onClick(() => {
            this.result = "";
            this.number = 0;
          }).myButton()
        }
      }
    }
  }
}

image.gif

6.模拟机运行测试  

image.gif 编辑 image.gif 编辑 image.gif 编辑

👋实验小结

       本次计算器应用开发实验主要围绕 index.ets 文件展开。利用按钮组件顺利完成布局设计,数字、运算符及功能按钮排列有序,操作逻辑清晰直观。点击事件处理精准,计算过程能实时且无误地呈现在 Text 组件,点击等号后计算函数高效解析表达式并给出准确结果,达成核心功能要求。然而,实验中也发现一些待改进之处,例如错误提示不够详尽,难以助力用户快速定位输入错误;界面美观性欠佳,颜色与样式缺乏精致感;响应式设计不足,在不同屏幕规格下适配性差。总体而言,本次实验已成功构建起基本功能框架,后续将针对上述问题深入探究优化方案,不断打磨细节,在完善计算器功能与提升用户体验的道路上持续精进,进而提升自身编程与应用开发的综合能力水平。

image.gif 编辑

目录
相关文章
|
2月前
|
JavaScript 安全 前端开发
【HarmonyOS开发】ArkTS基础语法及使用(鸿蒙开发基础教程)
【HarmonyOS开发】ArkTS基础语法及使用(鸿蒙开发基础教程)
350 4
|
8天前
|
存储 人工智能 JavaScript
Harmony OS开发-ArkTS语言速成二
本文介绍了ArkTS基础语法,包括三种基本数据类型(string、number、boolean)和变量的使用。重点讲解了let、const和var的区别,涵盖作用域、变量提升、重新赋值及初始化等方面。期待与你共同进步!
68 47
Harmony OS开发-ArkTS语言速成二
|
10天前
|
开发框架 JavaScript 前端开发
Harmony OS开发-ArkT语言速成一
本文介绍ArkTS语言,它是鸿蒙生态的应用开发语言,基于TypeScript,具有静态类型检查、声明式UI、组件化架构、响应式编程等特性,支持跨平台开发和高效性能优化。ArkTS通过强化静态检查和分析,提升代码健壮性和运行性能,适用于Web、移动端和桌面端应用开发。关注我,带你轻松掌握HarmonyOS开发。
40 5
Harmony OS开发-ArkT语言速成一
|
18天前
|
安全 数据安全/隐私保护 UED
HarmonyOS 5.0 (Next)应用开发实战:使用ArkTS构建开箱即用的登录页面【HarmonyOS 5.0(Next)】
### HarmonyOS 5.0(Next)应用开发实战:使用ArkTS构建开箱即用的登录页面 HarmonyOS 5.0(Next)融合了美学与科技,引入“光感美学”设计理念和多设备深度协同功能。本文通过 ArkTS 构建一个简单的登录页面,展示了模块化导入、状态管理、方法封装、声明式UI构建及事件处理等最佳实践。代码实现了一个包含用户名和密码输入框及登录按钮的界面,支持错误提示和页面跳转。
94 14
HarmonyOS 5.0 (Next)应用开发实战:使用ArkTS构建开箱即用的登录页面【HarmonyOS 5.0(Next)】
|
18天前
|
人工智能 自然语言处理 算法
开箱即用的个人主页页面开发实战—基于HarmonyOS 5.0 (Next)和ArkTS的实现【HarmonyOS 5.0(Next)】
本文介绍了基于HarmonyOS 5.0(Next)和ArkTS开发的开箱即用个人主页页面。HarmonyOS 5.0(Next)采用全新“和谐美学”设计理念,通过光元素模拟、多设备无缝流转及小艺助手升级,提升用户体验。文章详细解析了使用ArkTS构建个人主页页面的代码,展示了清晰的布局层次、简洁的事件处理、状态管理和组件化开发等最佳实践。这段代码不仅实现了美观的界面设计,还提供了高效的应用导航和数据传递功能,体现了对用户体验的高度关注。
118 12
开箱即用的个人主页页面开发实战—基于HarmonyOS 5.0 (Next)和ArkTS的实现【HarmonyOS 5.0(Next)】
|
18天前
|
自然语言处理 搜索推荐 数据安全/隐私保护
鸿蒙登录页面好看的样式设计-HarmonyOS应用开发实战与ArkTS代码解析【HarmonyOS 5.0(Next)】
鸿蒙登录页面设计展示了 HarmonyOS 5.0(Next)的未来美学理念,结合科技与艺术,为用户带来视觉盛宴。该页面使用 ArkTS 开发,支持个性化定制和无缝智能设备连接。代码解析涵盖了声明式 UI、状态管理、事件处理及路由导航等关键概念,帮助开发者快速上手 HarmonyOS 应用开发。通过这段代码,开发者可以了解如何构建交互式界面并实现跨设备协同工作,推动智能生态的发展。
128 10
鸿蒙登录页面好看的样式设计-HarmonyOS应用开发实战与ArkTS代码解析【HarmonyOS 5.0(Next)】
|
9天前
鸿蒙语言开发 几十套鸿蒙ArkTs app毕业设计及课程作业
鸿蒙语言开发 几十套鸿蒙ArkTs app毕业设计及课程作业
18 1
|
18天前
|
人工智能 安全 数据安全/隐私保护
HarmonyOS应用开发实战:基于ArkTS的开箱即用登录页面实现【样式方式实现①】【HarmonyOS 5.0(Next)】
本文介绍了基于HarmonyOS 5.0(Next)和ArkTS实现的开箱即用登录页面。HarmonyOS 5.0是华为于2024年10月22日发布的第三代移动操作系统,具备原生智能、互联、安全及流畅特性。文章详细解析了使用ArkTS开发登录页面的代码,涵盖组件定义、界面布局、事件处理、样式设置及异步操作等内容,展示了清晰的组件结构、响应式设计与模块化编程的优势。通过这段代码,开发者可以快速上手并构建高效、美观的应用界面。
137 9
|
30天前
|
存储 JSON 开发工具
三、HarmonyOS NEXT应用开发:ArkTS工程目录结构(Stage模型)
本文介绍了HarmonyOS NEXT应用开发中ArkTS工程的目录结构(Stage模型),包括AppScope、entry、hvigor、oh_modules等主要目录及其作用。重点解析了entry目录下的src > main > resources目录结构,详细说明了base、限定符目录和rawfile的作用,以及如何引用资源文件。
74 1
|
2月前
|
UED
鸿蒙next版开发:相机开发-适配不同折叠状态的摄像头变更(ArkTS)
在HarmonyOS 5.0中,ArkTS提供了强大的相机开发能力,特别是针对折叠屏设备的摄像头适配。本文详细介绍了如何在ArkTS中检测和适配不同折叠状态下的摄像头变更,确保相机应用在不同设备状态下的稳定性和用户体验。通过代码示例展示了具体的实现步骤。
90 8

热门文章

最新文章

下一篇
开通oss服务