Android开发实现简单计算器功能
计算器项目,要求实现加、减、乘、除、求倒数、求平方根等简单运算。
真机调试结果如下图:
布局文件: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'> <ScrollViewandroid:layout_width='match_parent'android:layout_height='wrap_content'><LinearLayout android:layout_width='match_parent' android:layout_height='wrap_content' android:orientation='vertical'> <TextViewandroid:layout_width='match_parent'android:layout_height='wrap_content'android:gravity='center'android:text='简单计算器'android:textColor='#000000'android:textSize='20sp' /> <LinearLayoutandroid:layout_width='match_parent'android:layout_height='wrap_content'android:background='#ffffff'android:orientation='vertical'><TextView android: 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> <GridLayoutandroid:layout_width='match_parent'android:layout_height='match_parent'android:columnCount='4'><Button android: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: android:layout_width='90dp' android:layout_height='70dp' android:backgroundTint='@color/gray' android:scaleType='centerInside' android:src='https://www.haobala.com/bcjs/@drawable/sqrt' android:gravity='center' android:layout_marginStart='4dp'/><Button android: 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: 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: 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: 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(); //存储运算式子的字符串构造器@Overrideprotected 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@Overridepublic 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;}}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持好吧啦网。
相关文章: