parent
a9eddb0ff6
commit
d02882f395
Binary file not shown.
@ -0,0 +1,314 @@
|
||||
package net.micode.myapplication;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
private TextView display;
|
||||
private TextView historyDisplay;
|
||||
private String currentInput = "";
|
||||
private String previousInput = "";
|
||||
private String operation = "";
|
||||
private boolean isNewCalculation = false;
|
||||
private String lastResult = "";
|
||||
private boolean hasOperation = false;
|
||||
// 新增错误状态标记
|
||||
private boolean hasError = false;
|
||||
private DecimalFormat decimalFormat = new DecimalFormat("#.##########");
|
||||
private List<String> historyList = new ArrayList<>();
|
||||
private SharedPreferences preferences;
|
||||
private static final String PREF_THEME = "theme_preference";
|
||||
private static final int THEME_LIGHT = 0;
|
||||
private static final int THEME_DARK = 1;
|
||||
private int currentTheme;
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
preferences = getSharedPreferences("CalculatorPrefs", MODE_PRIVATE);
|
||||
currentTheme = preferences.getInt(PREF_THEME, THEME_LIGHT);
|
||||
setTheme(currentTheme == THEME_DARK ? R.style.DarkTheme : R.style.LightTheme);
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
display = findViewById(R.id.display);
|
||||
historyDisplay = findViewById(R.id.history_display);
|
||||
if (savedInstanceState != null) {
|
||||
historyList = savedInstanceState.getStringArrayList("history");
|
||||
lastResult = savedInstanceState.getString("lastResult", "");
|
||||
hasOperation = savedInstanceState.getBoolean("hasOperation", false);
|
||||
hasError = savedInstanceState.getBoolean("hasError", false);
|
||||
updateDisplay(); // 错误状态需要恢复显示
|
||||
}
|
||||
setupNumberButton(R.id.btn_0, "0");
|
||||
setupNumberButton(R.id.btn_1, "1");
|
||||
setupNumberButton(R.id.btn_2, "2");
|
||||
setupNumberButton(R.id.btn_3, "3");
|
||||
setupNumberButton(R.id.btn_4, "4");
|
||||
setupNumberButton(R.id.btn_5, "5");
|
||||
setupNumberButton(R.id.btn_6, "6");
|
||||
setupNumberButton(R.id.btn_7, "7");
|
||||
setupNumberButton(R.id.btn_8, "8");
|
||||
setupNumberButton(R.id.btn_9, "9");
|
||||
setupNumberButton(R.id.btn_dot, ".");
|
||||
setupOperationButton(R.id.btn_add, "+");
|
||||
setupOperationButton(R.id.btn_subtract, "-");
|
||||
setupOperationButton(R.id.btn_multiply, "*");
|
||||
setupOperationButton(R.id.btn_divide, "/");
|
||||
setupScientificButton(R.id.btn_sin, "sin");
|
||||
setupScientificButton(R.id.btn_cos, "cos");
|
||||
setupScientificButton(R.id.btn_tan, "tan");
|
||||
setupScientificButton(R.id.btn_square, "x²");
|
||||
setupScientificButton(R.id.btn_sqrt, "√");
|
||||
findViewById(R.id.btn_equals).setOnClickListener(v -> calculateResult());
|
||||
findViewById(R.id.btn_clear).setOnClickListener(v -> clearAll());
|
||||
findViewById(R.id.btn_percent).setOnClickListener(v -> calculatePercentage());
|
||||
findViewById(R.id.btn_plus_minus).setOnClickListener(v -> changeSign());
|
||||
findViewById(R.id.btn_history).setOnClickListener(v -> showHistory());
|
||||
findViewById(R.id.btn_theme).setOnClickListener(v -> switchTheme());
|
||||
}
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putStringArrayList("history", new ArrayList<>(historyList));
|
||||
outState.putString("lastResult", lastResult);
|
||||
outState.putBoolean("hasOperation", hasOperation);
|
||||
outState.putBoolean("hasError", hasError);
|
||||
}
|
||||
private void setupNumberButton(int buttonId, String number) {
|
||||
Button button = findViewById(buttonId);
|
||||
button.setOnClickListener(v -> {
|
||||
// 错误状态下输入数字,清除错误并开始新计算
|
||||
if (hasError) {
|
||||
clearAll();
|
||||
hasError = false;
|
||||
}
|
||||
if (hasOperation && isNewCalculation && !lastResult.isEmpty()) {
|
||||
currentInput = lastResult;
|
||||
isNewCalculation = false;
|
||||
hasOperation = false;
|
||||
} else if (isNewCalculation && !lastResult.isEmpty()) {
|
||||
currentInput = lastResult;
|
||||
isNewCalculation = false;
|
||||
}
|
||||
if (number.equals(".") && currentInput.contains(".")) return;
|
||||
if (currentInput.equals("0") && !number.equals(".")) {
|
||||
currentInput = number;
|
||||
} else {
|
||||
currentInput += number;
|
||||
}
|
||||
updateDisplay();
|
||||
});
|
||||
}
|
||||
private void setupOperationButton(int buttonId, String op) {
|
||||
Button button = findViewById(buttonId);
|
||||
button.setOnClickListener(v -> {
|
||||
// 错误状态下输入操作符,清除错误并开始新计算
|
||||
if (hasError) {
|
||||
clearAll();
|
||||
hasError = false;
|
||||
}
|
||||
if (!currentInput.isEmpty() || !lastResult.isEmpty()) {
|
||||
String input = currentInput;
|
||||
if (currentInput.isEmpty() && !lastResult.isEmpty()) {
|
||||
input = lastResult;
|
||||
}
|
||||
if (!previousInput.isEmpty() && !operation.isEmpty() && !isNewCalculation) {
|
||||
calculateResult();
|
||||
// 若上次计算有错误,不更新操作符
|
||||
if (hasError) return;
|
||||
previousInput = lastResult;
|
||||
currentInput = "";
|
||||
operation = op;
|
||||
hasOperation = true;
|
||||
updateDisplay();
|
||||
return;
|
||||
}
|
||||
previousInput = input;
|
||||
currentInput = "";
|
||||
operation = op;
|
||||
hasOperation = true;
|
||||
isNewCalculation = false;
|
||||
updateDisplay();
|
||||
}
|
||||
});
|
||||
}
|
||||
private void setupScientificButton(int buttonId, String func) {
|
||||
Button button = findViewById(buttonId);
|
||||
button.setOnClickListener(v -> {
|
||||
// 错误状态下输入科学计算按钮,清除错误并开始新计算
|
||||
if (hasError) {
|
||||
clearAll();
|
||||
hasError = false;
|
||||
}
|
||||
String input = currentInput;
|
||||
if (isNewCalculation && !lastResult.isEmpty()) {
|
||||
input = lastResult;
|
||||
isNewCalculation = false;
|
||||
}
|
||||
if (!input.isEmpty()) {
|
||||
double value = Double.parseDouble(input);
|
||||
double result = 0;
|
||||
boolean errorOccurred = false;
|
||||
switch (func) {
|
||||
case "sin":
|
||||
result = Math.sin(Math.toRadians(value));
|
||||
break;
|
||||
case "cos":
|
||||
result = Math.cos(Math.toRadians(value));
|
||||
break;
|
||||
case "tan":
|
||||
result = Math.tan(Math.toRadians(value));
|
||||
break;
|
||||
case "x²":
|
||||
result = value * value;
|
||||
break;
|
||||
case "√":
|
||||
if (value < 0) {
|
||||
display.setText("Error");
|
||||
hasError = true;
|
||||
errorOccurred = true;
|
||||
} else {
|
||||
result = Math.sqrt(value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!errorOccurred) {
|
||||
currentInput = decimalFormat.format(result);
|
||||
lastResult = currentInput;
|
||||
hasOperation = false;
|
||||
updateDisplay();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
private void calculateResult() {
|
||||
if (hasError) return; // 错误状态下不执行计算
|
||||
if (previousInput.isEmpty() || (currentInput.isEmpty() && lastResult.isEmpty()) || operation.isEmpty()) return;
|
||||
double prev = Double.parseDouble(previousInput);
|
||||
double current = currentInput.isEmpty() ? Double.parseDouble(lastResult) : Double.parseDouble(currentInput);
|
||||
double result = 0;
|
||||
boolean errorOccurred = false;
|
||||
|
||||
// 除零错误处理核心逻辑
|
||||
if (operation.equals("/") && current == 0) {
|
||||
display.setText("不能除以0");
|
||||
hasError = true;
|
||||
errorOccurred = true;
|
||||
} else {
|
||||
switch (operation) {
|
||||
case "+":
|
||||
result = prev + current;
|
||||
break;
|
||||
case "-":
|
||||
result = prev - current;
|
||||
break;
|
||||
case "*":
|
||||
result = prev * current;
|
||||
break;
|
||||
case "/":
|
||||
result = prev / current;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!errorOccurred) {
|
||||
String historyItem = previousInput + " " + operation + " " +
|
||||
(currentInput.isEmpty() ? lastResult : currentInput) + " = " + result;
|
||||
historyList.add(historyItem);
|
||||
updateHistoryDisplay();
|
||||
currentInput = decimalFormat.format(result);
|
||||
lastResult = currentInput;
|
||||
previousInput = "";
|
||||
operation = "";
|
||||
isNewCalculation = true;
|
||||
hasOperation = false;
|
||||
updateDisplay();
|
||||
}
|
||||
}
|
||||
private void clearAll() {
|
||||
currentInput = "";
|
||||
previousInput = "";
|
||||
operation = "";
|
||||
lastResult = "";
|
||||
isNewCalculation = false;
|
||||
hasOperation = false;
|
||||
hasError = false; // 清除错误状态
|
||||
updateDisplay();
|
||||
}
|
||||
private void calculatePercentage() {
|
||||
if (hasError) {
|
||||
clearAll();
|
||||
hasError = false;
|
||||
}
|
||||
String input = currentInput;
|
||||
if (isNewCalculation && !lastResult.isEmpty()) {
|
||||
input = lastResult;
|
||||
isNewCalculation = false;
|
||||
}
|
||||
if (!input.isEmpty()) {
|
||||
double value = Double.parseDouble(input) / 100;
|
||||
currentInput = decimalFormat.format(value);
|
||||
lastResult = currentInput;
|
||||
hasOperation = false;
|
||||
updateDisplay();
|
||||
} else if (!previousInput.isEmpty()) {
|
||||
double value = Double.parseDouble(previousInput) / 100;
|
||||
previousInput = decimalFormat.format(value);
|
||||
updateDisplay();
|
||||
}
|
||||
}
|
||||
private void changeSign() {
|
||||
if (hasError) {
|
||||
clearAll();
|
||||
hasError = false;
|
||||
}
|
||||
String input = currentInput;
|
||||
if (isNewCalculation && !lastResult.isEmpty()) {
|
||||
input = lastResult;
|
||||
isNewCalculation = false;
|
||||
}
|
||||
if (!input.isEmpty()) {
|
||||
double value = Double.parseDouble(input);
|
||||
value = -value;
|
||||
currentInput = decimalFormat.format(value);
|
||||
lastResult = currentInput;
|
||||
hasOperation = false;
|
||||
updateDisplay();
|
||||
}
|
||||
}
|
||||
private void updateDisplay() {
|
||||
if (hasError) {
|
||||
display.setText("Error");
|
||||
return;
|
||||
}
|
||||
StringBuilder displayText = new StringBuilder();
|
||||
if (!previousInput.isEmpty()) {
|
||||
displayText.append(previousInput).append(" ");
|
||||
if (!operation.isEmpty()) {
|
||||
displayText.append(operation).append(" ");
|
||||
}
|
||||
}
|
||||
if (!currentInput.isEmpty()) {
|
||||
displayText.append(currentInput);
|
||||
}
|
||||
display.setText(displayText.toString());
|
||||
}
|
||||
private void updateHistoryDisplay() {
|
||||
StringBuilder historyText = new StringBuilder();
|
||||
for (int i = historyList.size() - 1; i >= 0; i--) {
|
||||
historyText.append(historyList.get(i)).append("\n");
|
||||
}
|
||||
historyDisplay.setText(historyText.toString());
|
||||
}
|
||||
private void showHistory() {
|
||||
updateHistoryDisplay();
|
||||
}
|
||||
private void switchTheme() {
|
||||
currentTheme = (currentTheme == THEME_LIGHT) ? THEME_DARK : THEME_LIGHT;
|
||||
preferences.edit().putInt(PREF_THEME, currentTheme).apply();
|
||||
recreate();
|
||||
}
|
||||
}
|
@ -0,0 +1,204 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:columnCount="4"
|
||||
android:rowCount="8"
|
||||
android:padding="10dp">
|
||||
|
||||
<!-- 历史记录显示区域 -->
|
||||
<TextView
|
||||
android:id="@+id/history_display"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_columnSpan="4"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:background="@android:color/white"
|
||||
android:gravity="end|top"
|
||||
android:minLines="2"
|
||||
android:padding="5dp"
|
||||
android:textSize="16sp"
|
||||
android:textColor="@android:color/darker_gray"/>
|
||||
|
||||
<!-- 显示区域 -->
|
||||
<EditText
|
||||
android:id="@+id/display"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_columnSpan="4"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:background="@android:color/darker_gray"
|
||||
android:gravity="end|bottom"
|
||||
android:minLines="2"
|
||||
android:padding="10dp"
|
||||
android:textSize="32sp"
|
||||
android:editable="false"
|
||||
android:cursorVisible="false"/>
|
||||
|
||||
<!-- 新增历史记录和主题按钮 -->
|
||||
<Button
|
||||
android:id="@+id/btn_history"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="历史"
|
||||
android:textSize="24sp"/>
|
||||
<Button
|
||||
android:id="@+id/btn_theme"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="主题"
|
||||
android:textSize="24sp"/>
|
||||
<Button
|
||||
android:id="@+id/btn_percent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="%"
|
||||
android:textSize="24sp"/>
|
||||
<Button
|
||||
android:id="@+id/btn_divide"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="/"
|
||||
android:textSize="24sp"/>
|
||||
|
||||
<!-- 科学计算按钮 -->
|
||||
<Button
|
||||
android:id="@+id/btn_sin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="sin"
|
||||
android:textSize="24sp"/>
|
||||
<Button
|
||||
android:id="@+id/btn_cos"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="cos"
|
||||
android:textSize="24sp"/>
|
||||
<Button
|
||||
android:id="@+id/btn_tan"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="tan"
|
||||
android:textSize="24sp"/>
|
||||
<Button
|
||||
android:id="@+id/btn_clear"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="C"
|
||||
android:textSize="24sp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_7"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="7"
|
||||
android:textSize="24sp"/>
|
||||
<Button
|
||||
android:id="@+id/btn_8"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="8"
|
||||
android:textSize="24sp"/>
|
||||
<Button
|
||||
android:id="@+id/btn_9"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="9"
|
||||
android:textSize="24sp"/>
|
||||
<Button
|
||||
android:id="@+id/btn_multiply"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="*"
|
||||
android:textSize="24sp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_4"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="4"
|
||||
android:textSize="24sp"/>
|
||||
<Button
|
||||
android:id="@+id/btn_5"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="5"
|
||||
android:textSize="24sp"/>
|
||||
<Button
|
||||
android:id="@+id/btn_6"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="6"
|
||||
android:textSize="24sp"/>
|
||||
<Button
|
||||
android:id="@+id/btn_subtract"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="-"
|
||||
android:textSize="24sp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="1"
|
||||
android:textSize="24sp"/>
|
||||
<Button
|
||||
android:id="@+id/btn_2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="2"
|
||||
android:textSize="24sp"/>
|
||||
<Button
|
||||
android:id="@+id/btn_3"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="3"
|
||||
android:textSize="24sp"/>
|
||||
<Button
|
||||
android:id="@+id/btn_add"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="+"
|
||||
android:textSize="24sp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_plus_minus"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="+/-"
|
||||
android:textSize="24sp"/>
|
||||
<Button
|
||||
android:id="@+id/btn_0"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_columnSpan="2"
|
||||
android:text="0"
|
||||
android:textSize="24sp"/>
|
||||
<Button
|
||||
android:id="@+id/btn_dot"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="."
|
||||
android:textSize="24sp"/>
|
||||
<Button
|
||||
android:id="@+id/btn_equals"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="="
|
||||
android:textSize="24sp"/>
|
||||
|
||||
<!-- 更多科学计算按钮 -->
|
||||
<Button
|
||||
android:id="@+id/btn_square"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="x²"
|
||||
android:textSize="24sp"/>
|
||||
<Button
|
||||
android:id="@+id/btn_sqrt"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="√"
|
||||
android:textSize="24sp"/>
|
||||
</GridLayout>
|
@ -0,0 +1,5 @@
|
||||
<resources>
|
||||
<color name="primary">#008577</color>
|
||||
<color name="primary_dark">#00574B</color>
|
||||
<color name="accent">#D81B60</color>
|
||||
</resources>
|
@ -0,0 +1,20 @@
|
||||
<resources>
|
||||
<!-- 基础主题 -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<item name="colorPrimary">@color/primary</item>
|
||||
<item name="colorPrimaryDark">@color/primary_dark</item>
|
||||
<item name="colorAccent">@color/accent</item>
|
||||
</style>
|
||||
|
||||
<!-- 浅色主题 -->
|
||||
<style name="LightTheme" parent="AppTheme">
|
||||
<item name="android:background">@android:color/white</item>
|
||||
<item name="android:textColor">@android:color/black</item>
|
||||
</style>
|
||||
|
||||
<!-- 深色主题 -->
|
||||
<style name="DarkTheme" parent="AppTheme">
|
||||
<item name="android:background">@android:color/darker_gray</item>
|
||||
<item name="android:textColor">@android:color/white</item>
|
||||
</style>
|
||||
</resources>
|
Loading…
Reference in new issue