案例演示

:::info
简易计算器案例需求

  1. 能够完成基本的加、减、乘、除运算
  2. 显示区域分为上下两部分,上部分显示算术表达式,下部分显示运算的结果
  3. 每次点击"="键时,完成算术表达式的运算,显示出结果;为了突出运算结果将结果字体放大,算术表达式字体缩小,并伴随有过渡动画。
  4. 每按下一个“数字键”或者“符号键”,按键会变色,同时按键会缩小为原来的0.9倍

:::

计算器界面

:::info
界面布局分析

  1. 如下图所示,计算器界面整体可以采用Column垂直布局
  2. 显示区域分别是两个Text。一个Text用于显示算术表达式,另一个Text用于显示运算结果
  3. 下面是键盘区域,采用Grid网格布局,每一个按键用GridItem来表示

:::

@Entry
@Component
struct Calculator {
  //所有按键显示的数据
  @State keyList: string[] = [
    'AC', '+/-', '%', '+',
    '7', '8', '9', '-',
    '4', '5', '6', '*',
    '1', '2', '3', '÷',
    '0', '.', '='
  ]
  //所有的操作符号(主要用于判断按键是否是操作符号,设置不同的样式)
  operatorList: string[] = ['AC', '+/-', '%', '+', '-', '*', '÷', '=']

  build() {
    Column() {
      Column() {
        Text("2561-9*3").fontWeight(FontWeight.Bold).fontSize(20)
        Text("2534").fontWeight(FontWeight.Bold).fontSize(30)
      }
      .width("100%")
      .height("30%")
      .alignItems(HorizontalAlign.End)
      .justifyContent(FlexAlign.End)
      .padding({ left: 10, right: 10, bottom: 10 })

      Column() {
        Grid(undefined, {
          regularSize: [1, 1],
          onGetRectByIndex: (index: number) => {
            if (index == 18) { // “18”指"="按键对应的index
              return [4, 2, 1, 2];
            }
            return [0, 0, 1, 1];
          }
        }) {
          ForEach(this.keyList, (text: string) => {
            this.KeyGridItem(text)
          })
        }
        .columnsTemplate("1fr 1fr 1fr 1fr")
        .rowsTemplate("1fr 1fr 1fr 1fr 1fr")
      }.width("100%")
      .layoutWeight(1)
    }
    .width('100%')
    .height('100%')
  }

  @Builder
  KeyGridItem(text: string) {
    GridItem() {
      Row() {
        Text(text)
          .width('100%')
          .fontSize(20)
          .height('100%')
          .textAlign(TextAlign.Center)
          .fontWeight(FontWeight.Bold)
          .fontColor(this.operatorList.includes(text) ? Color.Orange : Color.Black)
      }
      .height(65)
      .borderRadius(33)
      .backgroundColor("#f8f8f8")
      .stateStyles({
        pressed: { //按下的样式
          .backgroundColor("#f2f2f2") //背景
          .scale({
            //缩放
            centerX: "50%",
            centerY: 32.5,
            x: 0.9,
            y: 0.9
          })
          .animation({ duration: 200 }) //动画
          .shadow({
            //阴影
            color: '#F0F0F0',
            radius: 30
          })
        },
        normal: {
          .backgroundColor('#F8F8F8')
          .scale({
            centerX: "50%",
            centerY: 32.5,
            x: 1,
            y: 1
          })
          .shadow(undefined) //取消阴影
          .animation({ duration: 200 })
        } //正常的样式
      })
      .attributeModifier(new KeyGridItemModifyer(text))
    }
  }
}


//自定义一个动态样式的类
class KeyGridItemModifyer implements AttributeModifier<RowAttribute> {
  text: string

  constructor(text: string) {
    this.text = text
  }

  //正常状态的样式
  applyNormalAttribute(instance: RowAttribute): void {
    //instance设置样式的组件
    if (this.text === '=') {
      instance.width(155)
    } else {
      instance.width(65)
    }
  }
}

按键处理

:::info
点击计算器按键时需要更新算术表达式,给CalcGridItem中的Text添加点击事件来处理按键操作,由于数字键、符号键的操作逻辑不一样,所以需要分别进行处理。

:::

给按键添加点击事件

.onClick(()=>{
  this.keyOperation(text)
})

将按键处理封装成一个keyOperation()方法,根据不同的按键进行不同的逻辑处理。

public keyOperation(text: string) {
    switch (text) {
      case "+":
      case "-":
      case "*":
      case "÷":
        //this.handleOperator(content);
        break;

      case "%":
        //this.handlePercent(content)
        break

      case "AC":
        //this.clear();
        break;

      case "=":
        //this.calculateResult();
        break;

      case "+/-":
        //this.toggleSign();
        break;

      default:	//数字键操作
        //this.handleNumber(content); 
        break;
    }
  } 

数字按键处理

:::info
数据按键处理的需求:

  1. 如果表达式开头是0,则去掉开头的0
  2. 如果表达式末尾的数字包含小数点,则无法再次输入小数点
  3. 如果表达式以.开头,将开头“.”改为“0.”
  4. 如果表达式以"3+3.5+“格式开头,此时如果按“.”,则将按下的”.“改为"0.”
  5. 如果表达式以"3+3.5+0"格式结尾,此时如果按键不是"."而是数字,则截取末尾"0"的前面一部分,再拼接上数字。

:::

//处理数字键操作
handleNumber(number: string) {
  //1.1 如果表达式开头是0,则去掉开头的0
  if (this.currentExpression === '0' && number !== '.') {
    this.currentExpression = number
    return
  }

  //1.2 如果表达式末尾的数字包含小数点,则无法输入小数点
  const regex = /(\d*\.\d+)$|(\.)$/
  if (regex.test(this.currentExpression) && number === '.') {
    return
  }

  //1.3 如果表达式以.开头,将“.”改为“0.”
  //举例: .6-> 0.6
  if (this.currentExpression === '.') {
    this.currentExpression = "0."
  }

  //1.4如果表达式以"3+3.5+"格式开头,此时如果按"."则将“.”改为"0."
  if (/[\+\-\*÷]$/.test(this.currentExpression) && number==='.') {
    number = "0."
  }

  //1.5如果表达式以"3+3.5+0"格式结尾,此时如果按键不是".",则截取末尾"0"的前面一部分
  if (/[\+\-\*÷][0]$/.test(this.currentExpression) && number!=='.') {
    this.currentExpression = this.currentExpression.substring(0,this.currentExpression.length-1)
  } 

  //在表达式末尾拼接数字或者点
  this.currentExpression += number
} 

清零处理

:::info
AC键的处理逻辑如下

  1. 每次按下“AC”键,将算术表达式清空,同时将元素结果归0
  2. 将运算完成的状态isCompleted改为false

:::

//2. AC处理
public clear() {
  this.currentExpression = ''
  this.result = '0'
  this.isCompleted = false
}

加减乘除按键处理

:::info
加减乘除按键操作逻辑

  1. 正常情况直接在表达式后面拼接操作符即可
  2. 当然也需要处理一些非正常情况
    1. 如果表达式为"",则无法拼接操作符
    2. 如果表达式后缀以“+,-,*,÷”任何一个符号结尾,则删除最后一个符号,再拼接新的操作符

:::

//3. 加减乘除按键处理
public handleOperator(opeartor: string) {
  //3.1 如果表达式为"",则无法拼接操作符
  if (this.currentExpression ==='') {
    return
  }

  //3.2 如果表达式后缀以“+,-,*,÷”任何一个符号结尾,则删除最后一个符号
  if (/[\+\-\*÷]$/.test(this.currentExpression)) {
    this.currentExpression = this.currentExpression.substring(0, this.currentExpression.length - 1)
  }
  this.currentExpression += opeartor
}

百分号处理

:::info
百分号处理逻辑

  1. 当输入百分号时,需要检查算术表达式末尾是否为数字,只有末尾是数字百分号才能生效
  2. 当输入百分号时,将表达式末尾的数字转换为小数;如:“1000060%"转换为"100000.6”

:::

handlePercent(text: string) {
  //判断运算表达式的末尾是否以整数或者小数结尾
  let regexp = /\d+$|\d+\.\d+$/
  if (regexp.test(this.currentExpression)) {
    //获取算数表达式最后的整数或者小数,使其除以100
    let array = this.currentExpression.match(regexp)
    //如果array不为undifine则表示有匹配的数据
    if (array) {
      let lastNumber = array[0] //36
      //let newLastNumber = parseFloat(lastNumber)/100  //小数可能不精确
      //Decimal对象处理小数不精确问题
      let newLastNumber= new Decimal(parseFloat(lastNumber)).div(new Decimal(100)).toNumber()
      this.currentExpression = this.currentExpression.replace(regexp,`${newLastNumber}`)
    }
  }
}

处理正负数

:::info
处理正负数的逻辑

  1. 如果表达式是一个单独的数字,则直接在数字前面加"-“号,再次点击去掉”-"号
  2. 如果表达式是多项式,则判断表达式是否以"*-8"或者"÷-8"结尾
    1. 如果以"-“结尾,则改为”" ;如:6*-8 按“+/-”则变为 6*8
    2. 如果以"÷-“结尾,则改为"÷”;如: 6÷-8 按“+/-”则变为 6÷8
  3. 如果表达式是一个多项式,则判断表达式是否以”+8“或者"-8"结尾
    1. 如果"+8"改为"-8"; 如: 2+8按“+/-”则改为2-8
    2. 如果"-8"改为"+8"; 如: 2-8按“+/-”则改为2+8
  4. 如果表达式一个多项式,则判断表达式是否以”*8“或者”÷8“结尾
    1. 如果以"8"结尾,则改为"-8"
    2. 如果以"*-8"结尾,则改为"*8"

:::

toggleSign() {
  // 1. 如果表达式是一个单独的数字,则直接在数字前面加"-"号,再次点击去掉"-"号
  if (/^-?\d*\.?\d+$/.test(this.currentExpression)) {
    this.currentExpression = `${-parseFloat(this.currentExpression)}`
    return
  }

  // 2. 如果表达式是多项式,则判断表达式是否以"*-8"或者"÷-8"结尾
  // a. 如果以"*-"结尾,则改为"*"  ;如:6*-8 按“+/-”则变为 6*8
  // b. 如果以"÷-"结尾,则改为"÷";如: 6÷-8 按“+/-”则变为 6÷8
  const regex4 = /([*÷])(\-?\d*\.{0,1}\d+)$/;
  //比如:算数表示式为:7+2+3+3*-8,匹配之后的元素分布为:["*-8","*","-8"]
  let match = this.currentExpression.match(regex4)
  if (match) {
    let sign_number = match[0] //*-8
    let sign = match[1] //"*"
    let number = match[2] //-8

    this.currentExpression = this.currentExpression.slice(0, -sign_number.length) + sign + (-parseFloat(number))
    return
  }

  // 3. 如果表达式是一个多项式,则判断表达式是否以”+8“或者"-8"结尾
  // a. 如果"+8"改为"-8"; 如: 2+8按“+/-”则改为2-8
  // b. 如果"-8"改为"+8"; 如: 2-8按“+/-”则改为2+8
  const regex5 = /([+-])(\-?\d*\.{0,1}\d+)$/;
  //比如:算数表示式为:7+2+3+3+8,匹配之后的元素分布为:["+8","+","8"]
  let match2 = this.currentExpression.match(regex5)
  if (match2) {
    let sign_number = match2[0] //"+8"
    let sign = match2[1] //"+"
    let number = match2[2] //8

    this.currentExpression = this.currentExpression.slice(0, -sign_number.length)  +`${sign==="+"?"-":"+"}`+ (parseFloat(number))
    return
  }
} 

处理等号运算

  • 计算表达式工具类
import { HashMap } from '@kit.ArkTS';

export class math {
  public static evaluate(expression: string): number {
    const precedence = new HashMap<String, number>();
    precedence.set("+", 1);
    precedence.set("-", 1);
    precedence.set("*", 2);
    precedence.set("/", 2);

    const applyOperator = (operators: string[], values: number[]) => {
      const operator = operators.pop();
      if (operator) {
        const b = values.pop();
        const a = values.pop();
        if (a !== undefined && b !== undefined) {
          switch (operator) {
            case '+':
              values.push(a + b);
              break;
            case '-':
              values.push(a - b);
              break;
            case '*':
              values.push(a * b);
              break;
            case '/':
              values.push(a / b);
              break;
          }
        }
      }
    };

    const operators: string[] = [];
    const values: number[] = [];

    let i = 0;
    while (i < expression.length) {
      if (expression[i] === ' ') {
        i++;
        continue;
      }

      // 处理负数
      if (expression[i] === '-' && (i === 0 || !math.isNumeric(expression[i - 1]) && expression[i - 1] !== ')')) {
        let val = 0;
        let decimal = 1.0;
        let hasDecimal = false;
        i++; // 跳过负号
        while (i < expression.length && (math.isNumeric(expression[i]) || expression[i] === '.')) {
          if (expression[i] === '.') {
            hasDecimal = true;
          } else {
            if (hasDecimal) {
              decimal /= 10;
              val += parseInt(expression[i], 10) * decimal;
            } else {
              val = (val * 10) + parseInt(expression[i], 10);
            }
          }
          i++;
        }
        values.push(-val);
        i--; // 因为循环会再自增一次
      } else if (math.isNumeric(expression[i]) || expression[i] === '.') {
        let val = 0;
        let decimal = 1.0;
        let hasDecimal = false;
        while (i < expression.length && (math.isNumeric(expression[i]) || expression[i] === '.')) {
          if (expression[i] === '.') {
            hasDecimal = true;
          } else {
            if (hasDecimal) {
              decimal /= 10;
              val += parseInt(expression[i], 10) * decimal;
            } else {
              val = (val * 10) + parseInt(expression[i], 10);
            }
          }
          i++;
        }
        values.push(val);
        i--; // 因为循环会再自增一次
      } else if (precedence.hasKey(expression[i])) {
        while (operators.length > 0 &&
          precedence.get(operators[operators.length - 1])! >= precedence.get(expression[i])!) {
          applyOperator(operators, values);
        }
        operators.push(expression[i]);
      } else if (expression[i] === '(') {
        operators.push(expression[i]);
      } else if (expression[i] === ')') {
        while (operators[operators.length - 1] !== '(') {
          applyOperator(operators, values);
        }
        operators.pop(); // 移除 '('
      }
      i++;
    }

    while (operators.length) {
      applyOperator(operators, values);
    }

    return values[0];
  }

  public static isNumeric(char: string): boolean {
    return !isNaN(parseFloat(char));
  }
}
  • 开始计算
//6.计算算术表达式
public calculateResult() {
  //6.1 执行算术表达式
  //把"÷"替换为"/"
  this.currentExpression = this.currentExpression.replace("÷","/")
  this.result = math.evaluate(this.currentExpression).toString()
  //6.2 计算执行的结果,以便连续计算
  this.preResult = this.result
  //6.3 将计算完成的标记改为true
  animateTo({duration:500},()=>{
    this.isCompleted = true
  }) 
}

修改数字按键的处理逻辑,每次按下数字键之前,先判断上一次运算是否完成,如果完成了将算术表达式清空;同时将isCompleted指为false,表示下一次运算开始;

//修改处理数字键操作
handleNumber(number: string) {
  //判断是否运算完成
  if (this.isCompleted){
    this.currentExpression = ''
    this.isCompleted = false
  }
  //.....
}

连续计算

:::info
连续计算的业务逻辑:连续运算指的是拿着上一次的运算结果,做下一次运算

  1. 如果上一次计算已经完成,this.isCompleted = true,表示运算已经完成,并且记录了上一次运算的结果给preResult
  2. 如果上一步运算以完成,则将算术表达式替换为上一步的结果,并将isCompleted该为false,表示重新开始计算。

:::

加减乘除运算

handleOperator()函数开头,加入如下代码

//3. 加减乘除按键处理
public handleOperator(opeartor: string) {
  if (this.isCompleted){
    this.currentExpression = this.preResult
    this.isCompleted = false
  }
  //...
}

百分号运算

handlePercent()函数开头,加入如下代码

//4. 百分号处理
public handlePercent(precent: string) {
  if (this.isCompleted) {
    const number = parseFloat(this.preResult)
    this.currentExpression = (number/100.0).toString()
    this.isCompleted = false
    return
  }
  //...
}

正负数运算

toggleSign()函数开头,加入如下代码

//5. 处理正负数
public toggleSign() {
  if (this.isCompleted) {
    this.currentExpression = this.preResult
    this.isCompleted = false
  }
  //...
} 

再次计算自动归零

:::info
如果上一次运算已经完成,需要按”AC“才能进行下一次运算。我们可以在进行下一次运算时,自动归零。

:::

  • handleNumber()函数中,加入如下代码
public handleNumber(number: string) {
  //如果已经运算完成,再次点击数字时,清空所有操作
  if (this.isCompleted){
    this.clear()
  }
  //...
}

完整代码

import { Decimal } from '@kit.ArkTS'
import { math } from '../util/math'


@Entry
@Component
struct Calculator {
  //所有按键显示的数据
  @State keyList: string[] = [
    'AC', '+/-', '%', '+',
    '7', '8', '9', '-',
    '4', '5', '6', '*',
    '1', '2', '3', '÷',
    '0', '.', '='
  ]
  //所有的操作符号(主要用于判断按键是否是操作符号,设置不同的样式)
  operatorList: string[] = ['AC', '+/-', '%', '+', '-', '*', '÷', '=']
  //算数表达式
  @State currentExpression: string = ''
  @State result: string = '0'

  //记录一次运算是否完成
  @State isCompleted:boolean = false

  //记录上次运算的结果
  @State preResult:string = ''

  build() {
    Column() {
      Column() {
        Text(this.currentExpression).fontWeight(FontWeight.Bold).fontSize(20)
        Text(this.result).fontWeight(FontWeight.Bold).fontSize(30)
      }
      .width("100%")
      .height("30%")
      .alignItems(HorizontalAlign.End)
      .justifyContent(FlexAlign.End)
      .padding({ left: 10, right: 10, bottom: 10 })

      Column() {
        Grid(undefined, {
          regularSize: [1, 1],
          onGetRectByIndex: (index: number) => {
            if (index == 18) { // key1是“18”按键对应的index
              return [4, 2, 1, 2];
            }
            return [0, 0, 1, 1];
          }
        }) {
          ForEach(this.keyList, (text: string) => {
            this.KeyGridItem(text)
          })
        }
        .columnsTemplate("1fr 1fr 1fr 1fr")
        .rowsTemplate("1fr 1fr 1fr 1fr 1fr")
      }.width("100%")
      .layoutWeight(1)
    }
    .width('100%')
    .height('100%')
  }

  @Builder
  KeyGridItem(text: string) {
    GridItem() {
      Row() {
        Text(text)
          .width('100%')
          .fontSize(20)
          .height('100%')
          .textAlign(TextAlign.Center)
          .fontWeight(FontWeight.Bold)
          .fontColor(this.operatorList.includes(text) ? Color.Orange : Color.Black)
          .onClick(() => {
            this.keyOperation(text)
          })
      }
      .height(65)
      .borderRadius(33)
      .backgroundColor("#f8f8f8")
      .stateStyles({
        pressed: { //按下的样式
          .backgroundColor("#f2f2f2") //背景
          .scale({
            //缩放
            centerX: "50%",
            centerY: 32.5,
            x: 0.9,
            y: 0.9
          })
          .animation({ duration: 200 }) //动画
          .shadow({
            //阴影
            color: '#F0F0F0',
            radius: 30
          })
        },
        normal: {
          .backgroundColor('#F8F8F8')
          .scale({
            centerX: "50%",
            centerY: 32.5,
            x: 1,
            y: 1
          })
          .shadow(undefined) //取消阴影
          .animation({ duration: 200 })
        } //正常的样式
      })
      .attributeModifier(new KeyGridItemModifyer(text))
      .onClick(() => {
        this.keyOperation(text)
      })
    }
  }

  //按键处理
  keyOperation(text: string) {
    switch (text) {
      case "+":
      case "-":
      case "*":
      case "÷":
        this.handleOperator(text)
        break
      case "%":
        this.handlePercent(text)
        break

      case "AC":
        this.clear();
        break;

      case "=":
        this.calculateResult();
        break;

      case "+/-":
        this.toggleSign();
        break;

      default:
        this.handleNumber(text); //处理数字键操作
        break;
    } 
  }

  //处理“=”按键的操作
  calculateResult() {
    if (/[\+\-\*÷]$/.test(this.currentExpression)) {
      this.currentExpression = this.currentExpression.slice(0,-1)
    }
    
    this.result = `${math.evaluate(this.currentExpression.replace("÷","/"))}`
    //记录上一次运算的结果
    this.preResult = this.result
    this.isCompleted = true
  }

  //处理正负号按键
  toggleSign() {
    //如果运算已经完成,则将上一次运行的结果进行正负数处理
    if (this.isCompleted){
      this.currentExpression = this.preResult
      this.isCompleted = false
    }

    // 1. 如果表达式是一个单独的数字,则直接在数字前面加"-"号,再次点击去掉"-"号
    if (/^-?\d*\.?\d+$/.test(this.currentExpression)) {
      this.currentExpression = `${-parseFloat(this.currentExpression)}`
      return
    }

    // 2. 如果表达式是多项式,则判断表达式是否以"*-8"或者"÷-8"结尾
    // a. 如果以"*-"结尾,则改为"*"  ;如:6*-8 按“+/-”则变为 6*8
    // b. 如果以"÷-"结尾,则改为"÷";如: 6÷-8 按“+/-”则变为 6÷8
    const regex4 = /([*÷])(\-?\d*\.{0,1}\d+)$/;
    //比如:算数表示式为:7+2+3+3*-8,匹配之后的元素分布为:["*-8","*","-8"]
    let match = this.currentExpression.match(regex4)
    if (match) {
      let sign_number = match[0] //*-8
      let sign = match[1] //"*"
      let number = match[2] //-8

      this.currentExpression = this.currentExpression.slice(0, -sign_number.length) + sign + (-parseFloat(number))
      return
    }

    // 3. 如果表达式是一个多项式,则判断表达式是否以”+8“或者"-8"结尾
    // a. 如果"+8"改为"-8"; 如: 2+8按“+/-”则改为2-8
    // b. 如果"-8"改为"+8"; 如: 2-8按“+/-”则改为2+8
    const regex5 = /([+-])(\-?\d*\.{0,1}\d+)$/;
    //比如:算数表示式为:7+2+3+3+8,匹配之后的元素分布为:["+8","+","8"]
    let match2 = this.currentExpression.match(regex5)
    if (match2) {
      let sign_number = match2[0] //"+8"
      let sign = match2[1] //"+"
      let number = match2[2] //8

      this.currentExpression = this.currentExpression.slice(0, -sign_number.length)  +`${sign==="+"?"-":"+"}`+ (parseFloat(number))
      return
    }
  }

  //处理百分号
  handlePercent(text: string) {
    //判断运算表达式的末尾是否以整数或者小数结尾
    let regexp = /\d+$|\d+\.\d+$/
    if (regexp.test(this.currentExpression)) {
      //获取算数表达式最后的整数或者小数,使其除以100
      let array = this.currentExpression.match(regexp)
      //如果array不为undifine则表示有匹配的数据
      if (array) {
        let lastNumber = array[0] //36
        let newLastNumber = parseFloat(lastNumber) / 100 //小数可能不精确
        //Decimal对象处理小数不精确问题
        //let newLastNumber= new Decimal(parseFloat(lastNumber)).div(new Decimal(100)).toNumber()
        this.currentExpression = this.currentExpression.replace(regexp, `${newLastNumber}`)
      }
    }
  }

  //清零操作
  clear() {
    this.currentExpression = ''
    this.result = '0'
  }

  //处理数字键操作
  handleNumber(number: string) {
    //判断是否运算完成
    if (this.isCompleted){
      this.currentExpression = ''
      this.isCompleted = false
    }

    //1.1 如果表达式开头是0,则去掉开头的0
    if (this.currentExpression === '0' && number !== '.') {
      this.currentExpression = number
      return
    }

    //1.2 如果表达式末尾的数字包含小数点,则无法输入小数点
    const regex = /(\d*\.\d+)$|(\.)$/
    if (regex.test(this.currentExpression) && number === '.') {
      return
    }

    //1.3 如果表达式以.开头,将“.”改为“0.”
    //举例: .6-> 0.6
    if (this.currentExpression === '.') {
      this.currentExpression = "0."
    }

    //1.4如果表达式以"3+3.5+"格式开头,此时如果按"."则将“.”改为"0."
    if (/[\+\-\*÷]$/.test(this.currentExpression) && number === '.') {
      number = "0."
    }

    //1.5如果表达式以"3+3.5+0"格式结尾,此时如果按键不是".",则截取末尾"0"的前面一部分
    if (/[\+\-\*÷][0]$/.test(this.currentExpression) && number !== '.') {
      this.currentExpression = this.currentExpression.substring(0, this.currentExpression.length - 1)
    }

    //在表达式末尾拼接数字或者点
    this.currentExpression += number
  }

  //3. 加减乘除按键处理
  public handleOperator(opeartor: string) {
    //如果运行已经完成,则拿上一次运行的结果拼接上运算符
    if (this.isCompleted){
      this.currentExpression = this.preResult+opeartor
      this.isCompleted = false
    }

    //3.1 如果表达式为"",则无法拼接操作符
    if (this.currentExpression === '') {
      return
    }

    //3.2 如果表达式后缀以“+,-,*,÷”任何一个符号结尾,则删除最后一个符号
    if (/[\+\-\*÷]$/.test(this.currentExpression)) {
      this.currentExpression = this.currentExpression.substring(0, this.currentExpression.length - 1)
    }

    this.currentExpression += opeartor
  }
}


//自定义一个动态样式的类
class KeyGridItemModifyer implements AttributeModifier<RowAttribute> {
  text: string

  constructor(text: string) {
    this.text = text
  }

  //正常状态的样式
  applyNormalAttribute(instance: RowAttribute): void {
    //instance设置样式的组件
    if (this.text === '=') {
      instance.width(155)
    } else {
      instance.width(65)
    }
  }
}

对鸿蒙感兴趣的同学,可以考免费取鸿蒙开发者认证

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐