小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
文章目录
效果图
计算器设计思路
计算器的输入分为以下几种状态
- 初始状态(什么都没输入之前)
- 输入第一个数字
- 点击了运算符
- 输入第二个数字
- 点击了等号
计算器的输入内容分为
- 输入了数字
- 输入了“.”
- 输入了运算符
- 输入了“=”
计算器的设计思路就是根据输入内容(数字、点、运算符、等号)分别处理计算器的不同状态就可以了
比如,现在输入的是数字,要处理的就是
1、初始状态输入数字的情况
2、输入了第一个数字再输入数字的情况
3、点击了运算符输入数字的情况
4、输入了第二个数字再输入数字的情况
5、点击了等号输入数字的情况
代码实现
xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:orientation="vertical"
tools:context=".MainActivity">
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="doClick"
android:text="算式计算" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="doClick"
android:text="AC" />
</LinearLayout>
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:stretchColumns="0,1,2,3">
<TableRow android:layout_weight="1">
<Button
android:id="@+id/bt1"
android:layout_height="match_parent"
android:onClick="doClick"
android:text="7" />
<Button
android:id="@+id/bt2"
android:layout_height="match_parent"
android:onClick="doClick"
android:text="8" />
<Button
android:id="@+id/bt3"
android:layout_height="match_parent"
android:onClick="doClick"
android:text="9" />
<Button
android:id="@+id/bt4"
android:layout_height="match_parent"
android:onClick="doClick"
android:text="/" />
</TableRow>
<TableRow android:layout_weight="1">
<Button
android:id="@+id/bt5"
android:layout_height="match_parent"
android:onClick="doClick"
android:text="4" />
<Button
android:id="@+id/bt6"
android:layout_height="match_parent"
android:onClick="doClick"
android:text="5" />
<Button
android:id="@+id/bt7"
android:layout_height="match_parent"
android:onClick="doClick"
android:text="6" />
<Button
android:id="@+id/bt8"
android:layout_height="match_parent"
android:onClick="doClick"
android:text="*" />
</TableRow>
<TableRow android:layout_weight="1">
<Button
android:id="@+id/bt9"
android:layout_height="match_parent"
android:onClick="doClick"
android:text="1" />
<Button
android:id="@+id/bt10"
android:layout_height="match_parent"
android:onClick="doClick"
android:text="2" />
<Button
android:id="@+id/bt11"
android:layout_height="match_parent"
android:onClick="doClick"
android:text="3" />
<Button
android:id="@+id/bt12"
android:layout_height="match_parent"
android:onClick="doClick"
android:text="-" />
</TableRow>
<TableRow android:layout_weight="1">
<Button
android:id="@+id/bt13"
android:layout_height="match_parent"
android:onClick="doClick"
android:text="." />
<Button
android:id="@+id/bt14"
android:layout_height="match_parent"
android:onClick="doClick"
android:text="0" />
<Button
android:id="@+id/bt15"
android:layout_height="match_parent"
android:onClick="doClick"
android:text="=" />
<Button
android:id="@+id/bt16"
android:layout_height="match_parent"
android:onClick="doClick"
android:text="+" />
</TableRow>
</TableLayout>
</LinearLayout>
java
public class MainActivity extends AppCompatActivity {
private EditText editText;
/*
*计算器使用状态
* 0 初始状态
* 1 输入第一个数字
* 2 点击了运算符
* 3 输入第二个数字
* 4 点击了等号
* */
private int status;
private double d1;//第一个数字
private double d2;//第二个数字
private String op;//运算符
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = findViewById(R.id.editText);
editText.setText("0");
}
public void doClick(View v) {
switch (v.getId()) {
case R.id.button1:
f1();
break;
case R.id.button2:
reset();
break;
default:
f2(v);
break;
}
}
private void reset() {
status = 0;
d1 = 0;
d2 = 0;
op = null;
editText.setText("0");
}
private void f1() {
}
private void f2(View view) {
Button button = (Button) view;
String s = button.getText().toString();
/*
* 不同文本处理方式不同
* 数字
* 运算符
* /
* =
*/
if (s.matches("\\d")) {
shuzi(s);
} else if (s.matches("[+\\-*/]")) {
yunsuanfu(s);
} else if (s.equals(".")) {
dian();
} else if (s.equals("=")) {
denghao();
}
}
private void denghao() {
switch (status) {
case 0:
break;
case 1:
//输入第一个数字的时候点“=”
status = 4;
break;
case 2:
//输入运算符时,点击“=”
//微软默认计算器输入如下“5+=”结果为10
d2 = d1;
double d = jisuan(d1, op, d2);
editText.setText(String.valueOf(d));
status = 4;
break;
case 3:
d = jisuan(d1, op, d2);
editText.setText(String.valueOf(d));
status = 4;
break;
case 4:
//点完“=”再点“=”
//微软计算器输入“1+2=”,结果为“3”
//此时再点“=”,相当于在此结果上再加“2”
d1 = Double.parseDouble(editText.getText().toString());
jisuan(d1, op, d2);
break;
}
}
private void dian() {
//不同状态下点“.”字符
switch (status) {
case 0:
//初始状态下点“.”,会直接显示“0.”,此时的状态变成输入第一个数字
editText.setText("0.");
status = 1;
break;
case 1:
//输入第一个数字时,再点“.”,需要判断是否已经含有“.”
String s = editText.getText().toString();
if (!s.contains(".")) {
editText.append(".");
}
break;
case 2:
d2 = 0;
editText.setText("0.");
status = 3;
break;
case 3:
//因为之前已经定义“s”,不用重复定义,可以覆盖后边所有“s”
s = editText.getText().toString();
if (!s.contains(".")) {
editText.append(".");
}
break;
case 4:
//点完等号再点“.”,相当于一次新的运算
reset();
editText.setText("0.");
status = 1;
break;
}
}
private void yunsuanfu(String s) {
//不同状态下点击运算符
switch (status) {
//初始状态下点击运算符
case 0:
d1 = 0;
status = 2;
op = s;
break;
//正在输入第一个数
case 1:
op = s;
status = 2;
break;
//点完运算符,再点运算符
case 2:
op = s;
break;
//输入第二个数的时候点击运算符
case 3:
//求出上一次的结果作为新的计算的第一个数字
d1 = jisuan(d1, op, d2);
editText.setText(String.valueOf(d1));
op = s;
status = 2;
break;
case 4:
d1 = Double.parseDouble(editText.getText().toString());
op = s;
status = 2;
break;
}
}
private double jisuan(double a, String op, double b) {
double r = 0;
switch (op.charAt(0)) {
case '+':
r = a + b;
break;
case '-':
r = a - b;
break;
case '*':
r = a * b;
break;
case '/':
r = a / b;
break;
}
return r;
}
private void shuzi(String s) {
//在不同状态下点击数字按钮
switch (status) {
//初始状态下,点击数字按钮直接显示
case 0:
editText.setText(s);
d1 = Double.parseDouble(s);
status = 1;
break;
case 1:
editText.append(s);
d1 = Double.parseDouble(editText.getText().toString());
break;
//点击符号后输入第二个数字
case 2:
editText.setText(s);
d2 = Double.parseDouble(s);
status = 3;
break;
//输入第二个数字的状态
case 3:
editText.append(s);
d2 = Double.parseDouble(editText.getText().toString());
break;
//点完等号,再点数字。相当于一次新的计算
case 4:
editText.setText(s);
d1 = Double.parseDouble(s);
status = 1;
break;
}
}
}
注意:f1() 方法为算式计算器跳转方法。算式计算器的实现为下一篇文章