Android开发实现简单计算器功能
作者:智能云 时间:2022-10-17 09:18:16
计算器项目,要求实现加、减、乘、除、求倒数、求平方根等简单运算。
真机调试结果如下图:
布局文件:main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:orientation="vertical"
android:padding="3dp">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="简单计算器"
android:textColor="#000000"
android:textSize="20sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff"
android:orientation="vertical">
<TextView
android:id="@+id/tv_result"
android:background="#4E4B4B"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right|bottom"
android:lines="3"
android:maxLines="3"
android:scrollbars="vertical"
android:text="0"
android:textColor="#FFFFFF"
android:textSize="35sp" />
</LinearLayout>
<GridLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnCount="4"
>
<Button
android:id="@+id/btn_cancel"
android:layout_width="85dp"
android:layout_height="70dp"
android:backgroundTint="@color/gray"
android:gravity="center"
android:shadowColor="@color/purple_500"
android:text="CE"
android:textColor="@color/black"
android:textSize="30sp"
android:layout_marginStart="5dp"/>
<Button
android:id="@+id/btn_divide"
android:layout_width="85dp"
android:layout_height="70dp"
android:backgroundTint="@color/gray"
android:gravity="center"
android:text="÷"
android:textColor="@color/black"
android:textSize="30sp"
android:layout_marginStart="5dp"/>
<Button
android:id="@+id/btn_multiply"
android:layout_width="85dp"
android:layout_height="70dp"
android:backgroundTint="@color/gray"
android:gravity="center"
android:text="×"
android:textColor="@color/black"
android:textSize="30sp"
android:layout_marginStart="5dp"/>
<Button
android:id="@+id/btn_clear"
android:layout_width="85dp"
android:layout_height="70dp"
android:backgroundTint="@color/gray"
android:gravity="center"
android:text="C"
android:textColor="@color/black"
android:textSize="30sp"
android:layout_marginStart="5dp"/>
<Button
android:id="@+id/btn_seven"
android:layout_width="85dp"
android:layout_height="70dp"
android:backgroundTint="@color/gray"
android:gravity="center"
android:text="7"
android:textColor="@color/black"
android:textSize="30sp"
android:layout_marginStart="5dp"/>
<Button
android:id="@+id/btn_eight"
android:layout_width="85dp"
android:layout_height="70dp"
android:backgroundTint="@color/gray"
android:gravity="center"
android:text="8"
android:textColor="@color/black"
android:textSize="30sp"
android:layout_marginStart="5dp" />
<Button
android:id="@+id/btn_nine"
android:layout_width="85dp"
android:layout_height="70dp"
android:backgroundTint="@color/gray"
android:gravity="center"
android:text="9"
android:textColor="@color/black"
android:textSize="30sp"
android:layout_marginStart="5dp"/>
<Button
android:id="@+id/btn_plus"
android:layout_width="85dp"
android:layout_height="70dp"
android:backgroundTint="@color/gray"
android:gravity="center"
android:text="+"
android:textColor="@color/black"
android:textSize="30sp"
android:layout_marginStart="5dp"/>
<Button
android:id="@+id/btn_four"
android:layout_width="85dp"
android:layout_height="70dp"
android:backgroundTint="@color/gray"
android:gravity="center"
android:text="4"
android:textColor="@color/black"
android:textSize="30sp"
android:layout_marginStart="5dp"/>
<Button
android:id="@+id/btn_five"
android:layout_width="85dp"
android:layout_height="70dp"
android:backgroundTint="@color/gray"
android:gravity="center"
android:text="5"
android:textColor="@color/black"
android:textSize="30sp"
android:layout_marginStart="5dp"/>
<Button
android:id="@+id/btn_six"
android:layout_width="85dp"
android:layout_height="70dp"
android:backgroundTint="@color/gray"
android:gravity="center"
android:text="6"
android:textColor="@color/black"
android:textSize="30sp"
android:layout_marginStart="5dp"/>
<Button
android:id="@+id/btn_minus"
android:layout_width="85dp"
android:layout_height="70dp"
android:backgroundTint="@color/gray"
android:gravity="center"
android:text="-"
android:textColor="@color/black"
android:textSize="30sp"
android:layout_marginStart="5dp"/>
<Button
android:id="@+id/btn_one"
android:layout_width="85dp"
android:layout_height="70dp"
android:backgroundTint="@color/gray"
android:gravity="center"
android:text="1"
android:textColor="@color/black"
android:textSize="30sp"
android:layout_marginStart="5dp"/>
<Button
android:id="@+id/btn_two"
android:layout_width="85dp"
android:layout_height="70dp"
android:backgroundTint="@color/gray"
android:gravity="center"
android:text="2"
android:textColor="@color/black"
android:textSize="30sp"
android:layout_marginStart="5dp"/>
<Button
android:id="@+id/btn_three"
android:layout_width="85dp"
android:layout_height="70dp"
android:backgroundTint="@color/gray"
android:gravity="center"
android:text="3"
android:textColor="@color/black"
android:textSize="30sp"
android:layout_marginStart="5dp"/>
<ImageButton
android:id="@+id/ib_sqrt"
android:layout_width="90dp"
android:layout_height="70dp"
android:backgroundTint="@color/gray"
android:scaleType="centerInside"
android:src="@drawable/sqrt"
android:gravity="center"
android:layout_marginStart="4dp"/>
<Button
android:id="@+id/btn_reciprocal"
android:layout_width="85dp"
android:layout_height="70dp"
android:backgroundTint="@color/gray"
android:gravity="center"
android:text="1/x"
android:textColor="@color/black"
android:textSize="28sp"
android:layout_marginStart="5dp"/>
<Button
android:id="@+id/btn_zero"
android:layout_width="85dp"
android:layout_height="70dp"
android:backgroundTint="@color/gray"
android:gravity="center"
android:text="0"
android:textColor="@color/black"
android:textSize="30sp"
android:layout_marginStart="5dp"/>
<Button
android:id="@+id/btn_dot"
android:layout_width="85dp"
android:layout_height="70dp"
android:backgroundTint="@color/gray"
android:gravity="center"
android:text="."
android:textColor="@color/black"
android:textSize="30sp"
android:layout_marginStart="5dp"/>
<Button
android:id="@+id/btn_equal"
android:layout_width="85dp"
android:layout_height="70dp"
android:backgroundTint="@color/gray"
android:gravity="center"
android:text="="
android:textColor="@color/black"
android:textSize="30sp"
android:layout_marginStart="5dp"/>
</GridLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>
活动页面:MainActivity.java
package com.example.calculator;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.example.calculator.cal.CoreAlgorithm;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private TextView tv_result; // 声明一个文本视图对象
private double result =0; // 当前的计算结果
private String showText = ""; // 显示的文本内容
private final StringBuilder builder=new StringBuilder(); //存储运算式子的字符串构造器
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_result = findViewById(R.id.tv_result);
int[] buttonSeq={
R.id.btn_cancel, // “取消”按钮
R.id.btn_divide,// “除法”按钮
R.id.btn_multiply , // “乘法”按钮
R.id.btn_clear , // “清除”按钮
R.id.btn_seven , // 数字7
R.id.btn_eight , // 数字8
R.id.btn_nine , // 数字9
R.id.btn_plus , // “加法”按钮
R.id.btn_four , // 数字4
R.id.btn_five , // 数字5
R.id.btn_six , // 数字6
R.id.btn_minus , // “减法”按钮
R.id.btn_one , // 数字1
R.id.btn_two , // 数字2
R.id.btn_three , // 数字3
R.id.btn_reciprocal , // 求倒数按钮
R.id.btn_zero , // 数字0
R.id.btn_dot , // “小数点”按钮
R.id.btn_equal , // “等号”按钮
R.id.ib_sqrt // “开平方”按钮
};
for(int buttonId:buttonSeq)
findViewById(buttonId).setOnClickListener(this);
builder.append(0);
}
//符号分类
//数字
//四则运算符
//小数点
//根号,倒数,等号,直接出结果
//CE C
@Override
public void onClick(View v) {
int id=v.getId();
String inputText="";
// if(result!=0){ //如果结果不为0,则按照结果进行运算
// clear();
// builder.append(result);
// }
//若不为根号,因为根号按钮无法取值
if(id!=R.id.ib_sqrt) {
inputText = ((TextView) v).getText().toString();
//判断是否为数字、小数点以及四则运算符
if (inputText.matches("\\d|\\.")) { //输入是否为数字或点号
resultCheck();
if(builder.toString().equals("0")){
builder.deleteCharAt(builder.length()-1);}
builder.append(inputText);
if(verifyExp(builder.toString())){
refreshText(builder.toString()); //表达式正确刷新
}else{
builder.deleteCharAt(builder.length() - 1); //表达式不正确删除最后一位字符
}
} else if (inputText.matches("\\+|-|×|÷")) { //输入为四则运算符
resultCheck();
builder.append(inputText);
if(verifyExp(builder.toString())){
refreshText(builder.toString());
}else{ //更替运算符操作
builder.deleteCharAt(builder.length() - 1);
builder.deleteCharAt(builder.length() - 1);
builder.append(inputText);
refreshText(builder.toString());
}
}
else { //点击了CE C 1/X =
switch (inputText) {
case "CE":
resultCheck();
//有字符才能删除
if (builder.length() > 0) {
builder.deleteCharAt(builder.length() - 1);
refreshText(builder.toString());
} else {
Toast.makeText(this, "没有数字可删了", Toast.LENGTH_SHORT).show();
}
break;
case "C":
refreshText("");
result=0.0;
builder.delete(0, builder.length()); //builder清空
builder.append(0);
break;
case "1/x":
resultCheck();
result=1/(CoreAlgorithm.calExp(builder.toString()));
refreshText("1/("+builder.toString()+")=\n"+result);
break;
case "=":
resultCheck();
if(result==0.0) {
result = CoreAlgorithm.calExp(builder.toString());
// builder.append("=");//容易出错 ,按等号会把这个式子进行运算
refreshText(builder.toString() + "=\n" + result);
}
break;
default:
Toast.makeText(this, "error", Toast.LENGTH_SHORT).show();
}
}
}else{ // 点击了开根号,由于算法不支持有运算符在前,目前已经支持
resultCheck(); //经过一次检查结果被清零,结果存于builder中
result = Math.sqrt(CoreAlgorithm.calExp(builder.toString()));
refreshText("√(" + builder.toString() + ")=\n" + result);
}
}
//检查整个表达式
public boolean verifyExp(String exp){ //验证整个表达式是否合法
String lastNum="";
String[] sp=exp.split("\\+|-|×|÷"); //将操作数分割出来
char lastChar=exp.charAt(exp.length()-1); //获得最后一个字符
lastNum=sp[sp.length-1]; //取得最后一位操作数
if(String.valueOf(lastChar).matches("\\+|-|×|÷")) //如果当前符号为四则运算符
{
lastNum="";
return exp.matches(".*(\\d[+-×÷])|.*(\\.[+-×÷])"); //验证最后的运算符是否符合只有一个原则
}else{ //最后一位为运算数
return lastNum.matches("^[-]?\\d*\\.?\\d*"); //验证最后一位运算数是否合法
}
}
// 刷新文本显示
private void refreshText(String text) {
showText = text;
tv_result.setText(showText);
}
// 清空并初始化
private void clear() {
builder.delete(0, builder.length());
showText="";
}
//基本每个出结果的按钮都要执行一次这个函数
public void resultCheck(){ //运算结果检查,有结果用结果,结果不为数字进行处理
if(result!=0){ //如果结果不为0,则按照结果进行运算
String res=String.valueOf(result);
if(res.matches("^[-]?\\d*\\.?\\d*")){ //若为浮点数字
clear();
builder.append(result);
result=0; //结果不清零,检查的时候就会一直重复放入结果
}else{ //若结果为字母,分母为0会返回Infinity,以及负数开方
clear();
builder.append("0");
result=0;
}
}
if(builder.length()==0){
builder.append(0);
}
}
}
核心算法:CoreAlgorithm.java
package com.example.calculator.cal;
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CoreAlgorithm {
private static final Stack<Double> st = new Stack<>(); //原始数字栈
private static final Queue<Double> qu = new ArrayDeque<>(); //序列化数字队列,
private static final Queue<String> queOp = new ArrayDeque<>(); //符号队列
private static final Queue<String> newQueOp = new ArrayDeque<>();
public static double calExp(String exp) {
// String str="1+3*2-8/2+6";
// String str="1+3*2/1";
//本算法似乎不支持符号在前面,目前算法已经改进
//处理运算符在式子最后
if (exp.matches(".*[\\+\\-×÷]")) {
exp = exp.substring(0, exp.length() - 1);
}
String[] sp; //存放分割数组
//运算符在式子最前面
if (exp.matches("[\\+\\-×÷].*")) {
String fistElem=exp.substring(0,1); //截取首个字符
exp=exp.substring(1); //舍去首个字符
//分割字符,提取数字
sp = exp.split("\\+|-|×|÷");
if(fistElem.equals("-")){ //首个字符为负号
sp[0]="-"+sp[0]; //添加负号
}
}else{ //没有符号在前
sp = exp.split("\\+|-|×|÷");
}
//之前直接分割字符会导致,数组第一位为空,导致程序无法运行
for (int i = sp.length - 1; i >= 0; i--) {
if (sp[i].equals(".")) {
st.push(0.0); //替换点号
} else {
st.push(Double.parseDouble(sp[i]));
}
}
//寻找匹配字符串
Pattern p = Pattern.compile("\\+|-|×|÷");
Matcher m = p.matcher(exp);
while (m.find()) {
queOp.add(m.group());
}
// for(int i=sp.length-1;i>=0;i--){
// System.out.println(st.pop());
// }
// int size=queNum.size();
// for(int i=0;i<size;i++)
// System.out.println(queNum.poll());
//运算降级序列化
while (st.size() > 0) {
String currOp;
if (queOp.size() > 0) {
currOp = queOp.poll();
} else {
currOp = "0";
}
switch (currOp) {
case "×":
st.push(st.pop() * st.pop());
break;
case "÷":
st.push(st.pop() / st.pop());
break;
case "+":
qu.add(st.pop());
newQueOp.add("+");
break;
case "-":
qu.add(st.pop());
newQueOp.add("-");
break;
default:
qu.add(st.pop());
}
}
//正常运算
if (qu.size() > 0) {
double res = qu.poll();
while (qu.size() > 0) {
String op = "";
if (newQueOp.size() > 0) {
op = newQueOp.poll();
} else {
op = "none";
}
switch (op) {
case "+":
res += qu.poll();
break;
case "-":
res -= qu.poll();
break;
default:
System.out.println("none");
}
}
return res;
}
return 0.0;
}
}
来源:https://blog.csdn.net/Q1368089323/article/details/117935368
标签:Android,计算器
0
投稿
猜你喜欢
JavaSE的逻辑控制你了解吗
2023-01-07 01:32:22
C#中String和StringBuilder的简介与区别
2021-10-13 06:40:54
C#获取本地IP的四种方式示例详解
2023-04-16 00:52:50
从try-with-resources到ThreadLocal,优化你的代码编写方式
2023-11-11 03:19:52
浅谈MyBatis 如何执行一条 SQL语句
2023-10-17 19:36:03
浅谈图片上传利用request.getInputStream()获取文件流时遇到的问题
2023-10-18 10:36:43
Spring Data JPA 映射VO/DTO对象方式
2022-10-13 10:25:27
springboot用controller跳转html页面的实现
2022-08-15 06:57:51
Android 调用百度地图API示例
2023-11-18 00:40:37
SpringBoot使用SchedulingConfigurer实现多个定时任务多机器部署问题(推荐)
2021-09-17 07:19:20
Android 优化之卡顿优化的实现
2022-03-03 21:34:25
Android操作SQLite数据库(增、删、改、查、分页等)及ListView显示数据的方法详解
2022-11-28 10:03:09
Java数据结构之数组(动力节点之Java学院整理)
2023-09-23 21:20:12
Java 实战项目锤炼之网上花店商城的实现流程
2021-09-14 04:51:45
AOP之事务管理<aop:advisor>的两种配置方式
2023-11-24 22:55:06
C# 弹出窗口show()和showdialog()的两种方式
2022-05-08 17:12:36
解决Maven中关于依赖导入不进的问题
2023-09-05 23:13:08
Java中二叉树数据结构的实现示例
2023-08-07 03:10:58
Spring中AOP概念与两种动态代理模式原理详解
2023-04-13 01:21:54
C#中DataTable和List互转的示例代码
2022-08-25 21:40:06