Android開發(fā)實現(xiàn)簡單計算器功能
更新時間:2021年06月18日 10:21:43 作者:智能云
這篇文章主要為大家詳細介紹了Android開發(fā)實現(xiàn)簡單計算器,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
計算器項目,要求實現(xiàn)加、減、乘、除、求倒數(shù)、求平方根等簡單運算。
真機調(diào)試結(jié)果如下圖:

布局文件: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; // 當前的計算結(jié)果
private String showText = ""; // 顯示的文本內(nèi)容
private final StringBuilder builder=new StringBuilder(); //存儲運算式子的字符串構(gòu)造器
@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 , // 數(shù)字7
R.id.btn_eight , // 數(shù)字8
R.id.btn_nine , // 數(shù)字9
R.id.btn_plus , // “加法”按鈕
R.id.btn_four , // 數(shù)字4
R.id.btn_five , // 數(shù)字5
R.id.btn_six , // 數(shù)字6
R.id.btn_minus , // “減法”按鈕
R.id.btn_one , // 數(shù)字1
R.id.btn_two , // 數(shù)字2
R.id.btn_three , // 數(shù)字3
R.id.btn_reciprocal , // 求倒數(shù)按鈕
R.id.btn_zero , // 數(shù)字0
R.id.btn_dot , // “小數(shù)點”按鈕
R.id.btn_equal , // “等號”按鈕
R.id.ib_sqrt // “開平方”按鈕
};
for(int buttonId:buttonSeq)
findViewById(buttonId).setOnClickListener(this);
builder.append(0);
}
//符號分類
//數(shù)字
//四則運算符
//小數(shù)點
//根號,倒數(shù),等號,直接出結(jié)果
//CE C
@Override
public void onClick(View v) {
int id=v.getId();
String inputText="";
// if(result!=0){ //如果結(jié)果不為0,則按照結(jié)果進行運算
// clear();
// builder.append(result);
// }
//若不為根號,因為根號按鈕無法取值
if(id!=R.id.ib_sqrt) {
inputText = ((TextView) v).getText().toString();
//判斷是否為數(shù)字、小數(shù)點以及四則運算符
if (inputText.matches("\\d|\\.")) { //輸入是否為數(shù)字或點號
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, "沒有數(shù)字可刪了", 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{ // 點擊了開根號,由于算法不支持有運算符在前,目前已經(jīng)支持
resultCheck(); //經(jīng)過一次檢查結(jié)果被清零,結(jié)果存于builder中
result = Math.sqrt(CoreAlgorithm.calExp(builder.toString()));
refreshText("√(" + builder.toString() + ")=\n" + result);
}
}
//檢查整個表達式
public boolean verifyExp(String exp){ //驗證整個表達式是否合法
String lastNum="";
String[] sp=exp.split("\\+|-|×|÷"); //將操作數(shù)分割出來
char lastChar=exp.charAt(exp.length()-1); //獲得最后一個字符
lastNum=sp[sp.length-1]; //取得最后一位操作數(shù)
if(String.valueOf(lastChar).matches("\\+|-|×|÷")) //如果當前符號為四則運算符
{
lastNum="";
return exp.matches(".*(\\d[+-×÷])|.*(\\.[+-×÷])"); //驗證最后的運算符是否符合只有一個原則
}else{ //最后一位為運算數(shù)
return lastNum.matches("^[-]?\\d*\\.?\\d*"); //驗證最后一位運算數(shù)是否合法
}
}
// 刷新文本顯示
private void refreshText(String text) {
showText = text;
tv_result.setText(showText);
}
// 清空并初始化
private void clear() {
builder.delete(0, builder.length());
showText="";
}
//基本每個出結(jié)果的按鈕都要執(zhí)行一次這個函數(shù)
public void resultCheck(){ //運算結(jié)果檢查,有結(jié)果用結(jié)果,結(jié)果不為數(shù)字進行處理
if(result!=0){ //如果結(jié)果不為0,則按照結(jié)果進行運算
String res=String.valueOf(result);
if(res.matches("^[-]?\\d*\\.?\\d*")){ //若為浮點數(shù)字
clear();
builder.append(result);
result=0; //結(jié)果不清零,檢查的時候就會一直重復(fù)放入結(jié)果
}else{ //若結(jié)果為字母,分母為0會返回Infinity,以及負數(shù)開方
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<>(); //原始數(shù)字棧
private static final Queue<Double> qu = new ArrayDeque<>(); //序列化數(shù)字隊列,
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";
//本算法似乎不支持符號在前面,目前算法已經(jīng)改進
//處理運算符在式子最后
if (exp.matches(".*[\\+\\-×÷]")) {
exp = exp.substring(0, exp.length() - 1);
}
String[] sp; //存放分割數(shù)組
//運算符在式子最前面
if (exp.matches("[\\+\\-×÷].*")) {
String fistElem=exp.substring(0,1); //截取首個字符
exp=exp.substring(1); //舍去首個字符
//分割字符,提取數(shù)字
sp = exp.split("\\+|-|×|÷");
if(fistElem.equals("-")){ //首個字符為負號
sp[0]="-"+sp[0]; //添加負號
}
}else{ //沒有符號在前
sp = exp.split("\\+|-|×|÷");
}
//之前直接分割字符會導(dǎo)致,數(shù)組第一位為空,導(dǎo)致程序無法運行
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;
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android錄音功能的實現(xiàn)以及踩坑實戰(zhàn)記錄
在Android 開發(fā)過程中,有些功能是通用的,或者是多個業(yè)務(wù)方都需要使用的,下面這篇文章主要給大家介紹了關(guān)于Android錄音功能的實現(xiàn)以及踩坑的相關(guān)資料,需要的朋友可以參考下2022-06-06
Android開發(fā)之獲取LayoutInflater對象的方法總結(jié)
這篇文章主要介紹了Android開發(fā)之獲取LayoutInflater對象的方法,結(jié)合實例形式總結(jié)分析了Android獲取LayoutInflater對象的常用技巧,需要的朋友可以參考下2016-02-02
Android 自定義可拖拽View界面渲染刷新后不會自動回到起始位置
這篇文章主要介紹了Android 自定義可拖拽View界面渲染刷新后不會自動回到起始位置的實現(xiàn)代碼,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-02-02
Android4.0.x Home鍵事件攔截監(jiān)聽的方法
這篇文章主要介紹了Android4.0.x Home鍵事件攔截監(jiān)聽的方法,對比分析了2.3.x的實現(xiàn)方法,分析了4.0.x實現(xiàn)Home鍵事件攔截監(jiān)聽的相關(guān)技巧,需要的朋友可以參考下2016-02-02

