代碼功能概述
- 一個功能完整的鴻蒙簡易計算器應用,全面展示了ArkTS在用户交互、數學計算、狀態管理和界面佈局等方面的核心能力。主要功能包括:
基本數學運算:支持加、減、乘、除四則運算
實時計算顯示:實時顯示輸入表達式和計算結果
連續計算:支持連續運算,自動記憶上一次計算結果
輸入驗證:防止非法數學表達式,提供錯誤提示
界面交互:完整的數字鍵盤和操作符按鈕
清除功能:支持全部清除和逐位清除
通過這個示例,可以深入理解ArkTS如何實現複雜的用户交互和數學計算邏輯。
2. 代碼邏輯分析
應用採用"表達式驅動計算"的架構設計:
1. 初始化階段:應用啓動時,初始化計算器狀態和顯示內容
2. 狀態管理:使用多個@State裝飾器管理當前表達式、計算結果和運算狀態
3. 用户輸入流程:
· 數字按鈕 → 追加到當前表達式 → 實時驗證和顯示
· 操作符按鈕 → 驗證並追加操作符 → 更新運算狀態
· 等號按鈕 → 執行數學計算 → 顯示結果並重置狀態
· 清除按鈕 → 重置表達式或逐位刪除 → 恢復初始狀態
4. 計算邏輯:使用JavaScript的eval()函數執行數學表達式計算
錯誤處理:捕獲計算異常,顯示友好的錯誤信息
完整代碼
@Entry
@Component
struct CalculatorTutorial {
@State currentInput: string = '0';
@State currentExpression: string = '';
@State result: string = '';
@State lastOperator: string = '';
@State isResultShown: boolean = false;
@State history: string[] = [];
build() {
Column({ space: 0 }) {
// 歷史記錄顯示
this.BuildHistoryDisplay()
// 顯示區域
this.BuildDisplay()
// 按鈕區域
this.BuildButtonGrid()
}
.width('100%')
.height('100%')
.backgroundColor('#000000')
}
@Builder BuildHistoryDisplay() {
if (this.history.length > 0) {
Column({ space: 5 }) {
ForEach(this.history.slice(-3), (item: string) => {
Text(item)
.fontSize(14)
.fontColor('#666666')
.textAlign(TextAlign.End)
.width('100%')
.padding({ right: 20 })
})
}
.width('100%')
.height(60)
.justifyContent(FlexAlign.End)
}
}
@Builder BuildDisplay() {
Column({ space: 5 }) {
// 表達式顯示
if (this.currentExpression.length > 0) {
Text(this.currentExpression)
.fontSize(20)
.fontColor('#666666')
.textAlign(TextAlign.End)
.width('100%')
.padding({ right: 20 })
}
// 結果/輸入顯示
Text(this.currentInput)
.fontSize(48)
.fontWeight(FontWeight.Medium)
.fontColor('#FFFFFF')
.textAlign(TextAlign.End)
.width('100%')
.padding({ right: 20 })
.margin({ bottom: 20 })
}
.width('100%')
.height(120)
.justifyContent(FlexAlign.End)
}
@Builder BuildButtonGrid() {
const buttonLayout = [
['C', '±', '%', '÷'],
['7', '8', '9', '×'],
['4', '5', '6', '-'],
['1', '2', '3', '+'],
['0', '.', '=', '']
];
Column({ space: 12 }) {
ForEach(buttonLayout, (row: string[]) => {
Row({ space: 12 }) {
ForEach(row, (buttonText: string) => {
if (buttonText) {
this.BuildCalculatorButton(buttonText)
}
})
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
})
}
.width('100%')
.layoutWeight(1)
.padding({ left: 12, right: 12, bottom: 20 })
}
@Builder BuildCalculatorButton(text: string) {
const isNumber = !isNaN(Number(text));
const isOperator = ['÷', '×', '-', '+', '='].includes(text);
const isFunction = ['C', '±', '%', '.'].includes(text);
let buttonColor = '#333333';
let textColor = '#FFFFFF';
if (text === 'C') {
buttonColor = '#A5A5A5';
textColor = '#000000';
} else if (isOperator || text === '=') {
buttonColor = '#FF9500';
} else if (isFunction) {
buttonColor = '#A5A5A5';
}
const buttonWidth = text === '0' ? '48%' : '22%';
Button(text)
.onClick(() => {
this.handleButtonPress(text);
})
.backgroundColor(buttonColor)
.fontColor(textColor)
.fontSize(32)
.fontWeight(FontWeight.Medium)
.width(buttonWidth)
.height(80)
.borderRadius(40)
}
private handleButtonPress(buttonText: string): void {
switch(buttonText) {
case 'C':
this.clearAll();
break;
case '±':
this.toggleSign();
break;
case '%':
this.calculatePercentage();
break;
case '.':
this.addDecimalPoint();
break;
case '=':
this.calculateResult();
break;
case '÷':
case '×':
case '-':
case '+':
this.handleOperator(buttonText);
break;
default:
this.handleNumberInput(buttonText);
}
}
private handleNumberInput(number: string): void {
if (this.isResultShown) {
this.currentInput = number;
this.currentExpression = '';
this.isResultShown = false;
} else if (this.currentInput === '0') {
this.currentInput = number;
} else {
this.currentInput += number;
}
}
private handleOperator(operator: string): void {
if (this.isResultShown) {
this.currentExpression = this.currentInput + ' ' + operator + ' ';
this.currentInput = '0';
this.isResultShown = false;
} else {
if (this.currentExpression === '') {
this.currentExpression = this.currentInput + ' ' + operator + ' ';
} else {
this.currentExpression += this.currentInput + ' ' + operator + ' ';
}
this.currentInput = '0';
}
this.lastOperator = operator;
}
private calculateResult(): void {
if (this.currentExpression === '' || this.lastOperator === '') {
return;
}
try {
// 構建完整的表達式
let fullExpression = this.currentExpression + this.currentInput;
// 替換顯示符號為計算符號
fullExpression = fullExpression
.replace(/×/g, '*')
.replace(/÷/g, '/');
// 執行計算
const result = eval(fullExpression);
// 格式化結果
let formattedResult = '';
if (Number.isInteger(result)) {
formattedResult = result.toString();
} else {
formattedResult = parseFloat(result.toFixed(8)).toString();
// 移除末尾的零
formattedResult = formattedResult.replace(/\.?0+$/, '');
}
// 更新顯示
this.result = formattedResult;
this.currentInput = formattedResult;
// 添加到歷史記錄
const historyEntry = `${this.currentExpression}${this.currentInput} = ${formattedResult}`;
this.history.push(historyEntry);
if (this.history.length > 10) {
this.history.shift();
}
// 重置狀態
this.currentExpression = '';
this.lastOperator = '';
this.isResultShown = true;
} catch (error) {
this.currentInput = '錯誤';
this.currentExpression = '';
this.lastOperator = '';
this.isResultShown = false;
}
}
private clearAll(): void {
this.currentInput = '0';
this.currentExpression = '';
this.result = '';
this.lastOperator = '';
this.isResultShown = false;
}
private toggleSign(): void {
if (this.currentInput !== '0') {
if (this.currentInput.startsWith('-')) {
this.currentInput = this.currentInput.substring(1);
} else {
this.currentInput = '-' + this.currentInput;
}
}
}
private calculatePercentage(): void {
const value = parseFloat(this.currentInput);
if (!isNaN(value)) {
this.currentInput = (value / 100).toString();
}
}
private addDecimalPoint(): void {
if (this.isResultShown) {
this.currentInput = '0.';
this.currentExpression = '';
this.isResultShown = false;
} else if (!this.currentInput.includes('.')) {
this.currentInput += '.';
}
}
}
想入門鴻蒙開發又怕花冤枉錢?別錯過!現在能免費系統學 -- 從 ArkTS 面向對象核心的類和對象、繼承多態,到吃透 鴻蒙開發關鍵技能,還能衝刺鴻蒙基礎 +高級開發者證書,更驚喜的是考證成功還送好禮!快加入我的鴻蒙班,一起從入門到精通,班級鏈接: 點擊https://developer.huawei.com/consumer/cn/training/classDetail/b7365031334e4353a9a0fd6785bb0791?type=1?ha_source=hmosclass&ha_sourceId=89000248免費進入