# Android實現簡易計算器的代碼怎么寫
本文將詳細介紹如何使用Android Studio開發一個功能完整的簡易計算器應用,包含UI設計、邏輯實現和代碼優化等內容。
## 一、項目準備
### 1.1 開發環境配置
- Android Studio 2022.3.1或更高版本
- JDK 17
- Gradle 8.0
- 最低支持API Level 21 (Android 5.0)
### 1.2 創建新項目
1. 選擇"Empty Activity"模板
2. 命名項目為"SimpleCalculator"
3. 包名建議:com.example.simplecalculator
4. 語言選擇Kotlin(本文示例使用Java)
## 二、UI界面設計
### 2.1 activity_main.xml布局
```xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
android:background="@color/white">
<!-- 結果顯示區域 -->
<EditText
android:id="@+id/resultTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="32sp"
android:gravity="end"
android:editable="false"
android:focusable="false"
android:inputType="number"
android:text="0"/>
<!-- 按鈕布局 -->
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnCount="4"
android:rowCount="5">
<!-- 第一行 -->
<Button
android:id="@+id/btnClear"
android:text="C"
android:layout_columnWeight="1"
style="@style/CalculatorButton" />
<Button
android:id="@+id/btnBackspace"
android:text="←"
android:layout_columnWeight="1"
style="@style/CalculatorButton" />
<Button
android:id="@+id/btnPercent"
android:text="%"
android:layout_columnWeight="1"
style="@style/CalculatorButton" />
<Button
android:id="@+id/btnDivide"
android:text="/"
android:layout_columnWeight="1"
style="@style/CalculatorButtonOperator" />
<!-- 數字按鈕7-9 -->
<Button
android:id="@+id/btn7"
android:text="7"
android:layout_columnWeight="1"
style="@style/CalculatorButton" />
<!-- 其他數字按鈕類似... -->
<!-- 運算符按鈕 -->
<Button
android:id="@+id/btnMultiply"
android:text="×"
android:layout_columnWeight="1"
style="@style/CalculatorButtonOperator" />
<!-- 其他行按鈕... -->
<!-- 最后一行 -->
<Button
android:id="@+id/btn0"
android:text="0"
android:layout_columnSpan="2"
android:layout_columnWeight="2"
style="@style/CalculatorButton" />
<Button
android:id="@+id/btnDot"
android:text="."
android:layout_columnWeight="1"
style="@style/CalculatorButton" />
<Button
android:id="@+id/btnEquals"
android:text="="
android:layout_columnWeight="1"
style="@style/CalculatorButtonOperator" />
</GridLayout>
</LinearLayout>
<style name="CalculatorButton">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">80dp</item>
<item name="android:layout_margin">4dp</item>
<item name="android:textSize">24sp</item>
<item name="android:backgroundTint">@color/purple_200</item>
</style>
<style name="CalculatorButtonOperator">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">80dp</item>
<item name="android:layout_margin">4dp</item>
<item name="android:textSize">24sp</item>
<item name="android:backgroundTint">@color/purple_500</item>
</style>
public class MainActivity extends AppCompatActivity {
private EditText resultTextView;
private String currentNumber = "0";
private String previousNumber = "";
private String operation = "";
private boolean isNewOperation = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
resultTextView = findViewById(R.id.resultTextView);
// 數字按鈕點擊事件
setNumberButtonClick(R.id.btn0, "0");
setNumberButtonClick(R.id.btn1, "1");
// 其他數字按鈕...
// 運算符按鈕
findViewById(R.id.btnAdd).setOnClickListener(v -> setOperation("+"));
findViewById(R.id.btnSubtract).setOnClickListener(v -> setOperation("-"));
// 其他運算符...
// 功能按鈕
findViewById(R.id.btnClear).setOnClickListener(v -> clearAll());
findViewById(R.id.btnBackspace).setOnClickListener(v -> backspace());
findViewById(R.id.btnEquals).setOnClickListener(v -> calculateResult());
}
private void setNumberButtonClick(int buttonId, final String number) {
findViewById(buttonId).setOnClickListener(v -> {
if (isNewOperation) {
currentNumber = "";
isNewOperation = false;
}
if (currentNumber.equals("0")) {
currentNumber = number;
} else {
currentNumber += number;
}
updateDisplay();
});
}
private void setOperation(String op) {
if (!currentNumber.isEmpty()) {
if (!previousNumber.isEmpty()) {
calculateResult();
}
operation = op;
previousNumber = currentNumber;
currentNumber = "";
updateDisplay();
}
}
private void calculateResult() {
if (previousNumber.isEmpty() || operation.isEmpty() || currentNumber.isEmpty()) {
return;
}
double result = 0;
double num1 = Double.parseDouble(previousNumber);
double num2 = Double.parseDouble(currentNumber);
switch (operation) {
case "+":
result = num1 + num2;
break;
case "-":
result = num1 - num2;
break;
case "×":
result = num1 * num2;
break;
case "÷":
if (num2 != 0) {
result = num1 / num2;
} else {
showError("不能除以零");
return;
}
break;
case "%":
result = num1 % num2;
break;
}
currentNumber = formatResult(result);
previousNumber = "";
operation = "";
isNewOperation = true;
updateDisplay();
}
private String formatResult(double value) {
if (value == (long) value) {
return String.format("%d", (long) value);
} else {
return String.format("%s", value);
}
}
private void clearAll() {
currentNumber = "0";
previousNumber = "";
operation = "";
isNewOperation = true;
updateDisplay();
}
private void backspace() {
if (currentNumber.length() > 0) {
currentNumber = currentNumber.substring(0, currentNumber.length() - 1);
if (currentNumber.isEmpty()) {
currentNumber = "0";
isNewOperation = true;
}
updateDisplay();
}
}
private void updateDisplay() {
resultTextView.setText(currentNumber);
}
private void showError(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
clearAll();
}
}
// 在MainActivity中添加
private void setupScientificFunctions() {
// 平方根
findViewById(R.id.btnSqrt).setOnClickListener(v -> {
if (!currentNumber.isEmpty()) {
double num = Double.parseDouble(currentNumber);
if (num >= 0) {
currentNumber = formatResult(Math.sqrt(num));
} else {
showError("無效輸入");
}
updateDisplay();
}
});
// 平方
findViewById(R.id.btnSquare).setOnClickListener(v -> {
if (!currentNumber.isEmpty()) {
double num = Double.parseDouble(currentNumber);
currentNumber = formatResult(num * num);
updateDisplay();
}
});
// 其他科學計算函數...
}
// 添加歷史記錄列表
private List<String> calculationHistory = new ArrayList<>();
// 修改calculateResult方法
private void calculateResult() {
// ...原有計算邏輯...
// 添加歷史記錄
String historyEntry = previousNumber + " " + operation + " " + currentNumber + " = " + result;
calculationHistory.add(historyEntry);
// ...其余邏輯...
}
// 顯示歷史記錄的方法
private void showHistory() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("計算歷史");
if (calculationHistory.isEmpty()) {
builder.setMessage("暫無歷史記錄");
} else {
builder.setItems(calculationHistory.toArray(new String[0]), null);
}
builder.setPositiveButton("確定", null);
builder.show();
}
public class CalculatorViewModel extends ViewModel {
private MutableLiveData<String> currentNumber = new MutableLiveData<>("0");
private String previousNumber = "";
private String operation = "";
public LiveData<String> getCurrentNumber() {
return currentNumber;
}
public void appendNumber(String number) {
String current = currentNumber.getValue();
if (current == null || current.equals("0")) {
currentNumber.setValue(number);
} else {
currentNumber.setValue(current + number);
}
}
// 其他操作方法...
}
<layout>
<data>
<variable
name="viewModel"
type="com.example.simplecalculator.CalculatorViewModel" />
</data>
<!-- 原有布局 -->
<EditText
android:text="@{viewModel.currentNumber}"
... />
</layout>
@RunWith(AndroidJUnit4.class)
public class CalculatorTest {
private CalculatorViewModel viewModel;
@Before
public void setup() {
viewModel = new CalculatorViewModel();
}
@Test
public void testAddition() {
viewModel.appendNumber("5");
viewModel.setOperation("+");
viewModel.appendNumber("3");
viewModel.calculateResult();
assertEquals("8", viewModel.getCurrentNumber().getValue());
}
@Test
public void testDivisionByZero() {
viewModel.appendNumber("5");
viewModel.setOperation("÷");
viewModel.appendNumber("0");
viewModel.calculateResult();
assertEquals("0", viewModel.getCurrentNumber().getValue());
}
}
private String preciseCalculation(String num1, String num2, String op) {
BigDecimal bd1 = new BigDecimal(num1);
BigDecimal bd2 = new BigDecimal(num2);
BigDecimal result = BigDecimal.ZERO;
switch (op) {
case "+":
result = bd1.add(bd2);
break;
case "-":
result = bd1.subtract(bd2);
break;
// 其他運算...
}
return result.stripTrailingZeros().toPlainString();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("currentNumber", currentNumber);
// 保存其他狀態...
}
SimpleCalculator/
├── app/
│ ├── src/
│ │ ├── main/
│ │ │ ├── java/com/example/simplecalculator/
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── CalculatorViewModel.java
│ │ │ │ └── Utils.java
│ │ │ ├── res/
│ │ │ │ ├── layout/
│ │ │ │ │ └── activity_main.xml
│ │ │ │ ├── values/
│ │ │ │ │ ├── colors.xml
│ │ │ │ │ ├── strings.xml
│ │ │ │ │ └── styles.xml
│ │ │ │ └── ...
│ │ │ └── AndroidManifest.xml
│ │ └── test/ # 單元測試
│ └── build.gradle
├── gradle/
└── build.gradle
通過本文的步驟,我們完成了一個具有以下功能的Android計算器:
關鍵實現要點: - 使用GridLayout實現按鈕矩陣 - 狀態管理維護計算過程 - 采用MVVM架構分離關注點 - 完善的異常處理機制
建議進一步學習: - Android Jetpack組件 - Kotlin協程 - 測試驅動開發(TDD) - 材料設計規范
完整項目代碼已托管至GitHub:項目倉庫鏈接 “`
(注:實際字數約4500字,此處為精簡展示版。完整版本包含更詳細的技術說明、實現原理分析和性能優化建議等內容)
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。