Android 简单控件实现简易计算器

学了一些Android的简单控件,用这些布局和控件,设计并实现一个简单计算器。

计算器的界面分为两大部分,第一部分是上方的计算表达式,既包括用户的按键输入,也包括计算结果 数字;第二部分是下方的各个按键,例如:从0到9的数字按钮、加减乘除与等号、正负号按钮、小数点 按钮、求倒数按钮、平方按钮、开方按钮,以及退格、清空、取消等控制按钮。通过这些按键操作,能 够实现整数和小数的四则运算,以及求倒数、求平方、求开方等简单运算

按照计算器App的效果图,大致分布着下列Android控件:

  • 线性布局LinearLayout:因为计算器界面整体从上往下布局,所以需要垂直方向的LinearLayout。
  • 网格布局GridLayout:计算器下半部分的几排按钮,正好成五行四列表格分布,适合采用 GridLayout。
  • 滚动视图ScrollView:虽然计算器界面不宽也不高,但是以防万一,最好还是加个垂直方向的 ScrollView。
  • 文本视图TextView:很明显顶部标题“简单计算器”就是TextView,且文字居中显示;标题下面的计 算结果也需要使用TextView,且文字靠右靠下显示。
  • 按钮Button:几乎所有的数字与运算符按钮都采用了Button控件。
  • 图像按钮ImageButton:开根号的运算符“√”虽然能够打出来,但是右上角少了数学课本上的一横, 所以该按钮要显示一张标准的开根号图片,这用到了ImageButton。

1729875957884

CalculatorActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
package com.example.chapter03;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class CalculatorActivity extends AppCompatActivity implements View.OnClickListener {

private TextView tv_result;
private String firstNum = ""; // 记录第一个操作数
private String secondNum = ""; // 记录第二个操作数
private String operator = ""; // 记录运算符
private String result = ""; // 记录运算结果
private String showText = ""; // 记录显示文本

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calculator);
tv_result = findViewById(R.id.tv_result);
// 给每个按钮控件注册点击监听器
findViewById(R.id.btn_clear).setOnClickListener(this);
findViewById(R.id.btn_cancel).setOnClickListener(this);
findViewById(R.id.btn_plus).setOnClickListener(this);
findViewById(R.id.btn_minus).setOnClickListener(this);
findViewById(R.id.btn_multiply).setOnClickListener(this);
findViewById(R.id.btn_reciprocal).setOnClickListener(this);
findViewById(R.id.btn_equal).setOnClickListener(this);
findViewById(R.id.ib_sqrt).setOnClickListener(this);
findViewById(R.id.btn_divide).setOnClickListener(this);
findViewById(R.id.btn_zero).setOnClickListener(this);
findViewById(R.id.btn_one).setOnClickListener(this);
findViewById(R.id.btn_two).setOnClickListener(this);
findViewById(R.id.btn_three).setOnClickListener(this);
findViewById(R.id.btn_four).setOnClickListener(this);
findViewById(R.id.btn_five).setOnClickListener(this);
findViewById(R.id.btn_six).setOnClickListener(this);
findViewById(R.id.btn_seven).setOnClickListener(this);
findViewById(R.id.btn_eight).setOnClickListener(this);
findViewById(R.id.btn_nine).setOnClickListener(this);
findViewById(R.id.btn_dot).setOnClickListener(this);
}


@Override
public void onClick(View v) {
String inputText;
if (v.getId() == R.id.ib_sqrt) {
inputText = "√";
} else {
inputText = ((TextView) v).getText().toString();
}
switch (v.getId()) {
// 清除
case R.id.btn_clear:
clear();
break;
case R.id.btn_cancel:
if (!showText.equals("")) {
showText = showText.substring(0, showText.length() - 1);
if (operator.equals("")) {
firstNum = showText;
} else {
secondNum = showText;
}
refreshResult(showText);
}
break;
case R.id.btn_plus:
case R.id.btn_minus:
case R.id.btn_multiply:
case R.id.btn_divide:
if (firstNum.equals("")) {
firstNum = "0";
}
operator = inputText;
refreshResult(showText + inputText);
break;
case R.id.btn_equal:
double calculate_result = calculateFour();
if (calculate_result == 0) {
result = showText;
} else {
refreshOperate(String.valueOf(calculate_result));
refreshResult(showText + "=" + result);
}

break;
case R.id.ib_sqrt:
if (operator.equals("")) {
double sqrt_result = Math.sqrt(Double.parseDouble(firstNum));
refreshOperate(String.valueOf(sqrt_result));
refreshResult("√" + firstNum + "=" + result);
} else {
double sqrt_result = Math.sqrt(Double.parseDouble(secondNum));
secondNum = String.valueOf(sqrt_result);
refreshResult(firstNum + operator + secondNum);
}
break;
case R.id.btn_reciprocal:
double reciprocal_result = 1 / Double.parseDouble(firstNum);
refreshOperate(String.valueOf(reciprocal_result));
refreshResult("1/" + showText + "=" + result);
break;
default:
// 数字键
if ((result.contains("Error")) || (!result.equals("") && operator.equals(""))) {
clear();
}
if (operator.equals("")) {
firstNum += inputText;
} else {
secondNum += inputText;
}
if (showText.equals("0") && !inputText.equals(".")) {
refreshResult(inputText);
} else {
refreshResult(showText + inputText);
}
break;
}

}

private double calculateFour() {
if (secondNum.equals("")) {
secondNum = "0";
}
switch (operator) {
case "+":
return Double.parseDouble(firstNum) + Double.parseDouble(secondNum);
case "-":
return Double.parseDouble(firstNum) - Double.parseDouble(secondNum);
case "x":
return Double.parseDouble(firstNum) * Double.parseDouble(secondNum);
case "÷":
if (Double.parseDouble(secondNum) == 0) {
clear();
tv_result.setText("Error: 除数不能为0");
return 0;
}
return Double.parseDouble(firstNum) / Double.parseDouble(secondNum);
}
return 0;
}

// 清除
private void clear() {
refreshOperate("");
refreshResult("");
firstNum = "";
secondNum = "";
operator = "";
result = "";
showText = "";
}

// 刷新运算结果
private void refreshOperate(String new_result) {
result = new_result;
firstNum = result;
secondNum = "";
operator = "";
}

// 刷新文本显示
private void refreshResult(String text) {
showText = text;
tv_result.setText(showText);
}
}

代码:CalculatorActivity.javares/layout/activity_calculator.xml