Android開發(fā)實(shí)現(xiàn)簡單計(jì)算器功能
計(jì)算器項(xiàng)目,要求實(shí)現(xiàn)加、減、乘、除、求倒數(shù)、求平方根等簡單運(yùn)算。
真機(jī)調(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="簡單計(jì)算器"
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>
活動(dòng)頁面: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; // 聲明一個(gè)文本視圖對(duì)象
private double result =0; // 當(dāng)前的計(jì)算結(jié)果
private String showText = ""; // 顯示的文本內(nèi)容
private final StringBuilder builder=new StringBuilder(); //存儲(chǔ)運(yùn)算式子的字符串構(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ù)點(diǎn)”按鈕
R.id.btn_equal , // “等號(hào)”按鈕
R.id.ib_sqrt // “開平方”按鈕
};
for(int buttonId:buttonSeq)
findViewById(buttonId).setOnClickListener(this);
builder.append(0);
}
//符號(hào)分類
//數(shù)字
//四則運(yùn)算符
//小數(shù)點(diǎn)
//根號(hào),倒數(shù),等號(hào),直接出結(jié)果
//CE C
@Override
public void onClick(View v) {
int id=v.getId();
String inputText="";
// if(result!=0){ //如果結(jié)果不為0,則按照結(jié)果進(jìn)行運(yùn)算
// clear();
// builder.append(result);
// }
//若不為根號(hào),因?yàn)楦?hào)按鈕無法取值
if(id!=R.id.ib_sqrt) {
inputText = ((TextView) v).getText().toString();
//判斷是否為數(shù)字、小數(shù)點(diǎn)以及四則運(yùn)算符
if (inputText.matches("\\d|\\.")) { //輸入是否為數(shù)字或點(diǎn)號(hào)
resultCheck();
if(builder.toString().equals("0")){
builder.deleteCharAt(builder.length()-1);}
builder.append(inputText);
if(verifyExp(builder.toString())){
refreshText(builder.toString()); //表達(dá)式正確刷新
}else{
builder.deleteCharAt(builder.length() - 1); //表達(dá)式不正確刪除最后一位字符
}
} else if (inputText.matches("\\+|-|×|÷")) { //輸入為四則運(yùn)算符
resultCheck();
builder.append(inputText);
if(verifyExp(builder.toString())){
refreshText(builder.toString());
}else{ //更替運(yùn)算符操作
builder.deleteCharAt(builder.length() - 1);
builder.deleteCharAt(builder.length() - 1);
builder.append(inputText);
refreshText(builder.toString());
}
}
else { //點(diǎn)擊了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("=");//容易出錯(cuò) ,按等號(hào)會(huì)把這個(gè)式子進(jìn)行運(yùn)算
refreshText(builder.toString() + "=\n" + result);
}
break;
default:
Toast.makeText(this, "error", Toast.LENGTH_SHORT).show();
}
}
}else{ // 點(diǎn)擊了開根號(hào),由于算法不支持有運(yùn)算符在前,目前已經(jīng)支持
resultCheck(); //經(jīng)過一次檢查結(jié)果被清零,結(jié)果存于builder中
result = Math.sqrt(CoreAlgorithm.calExp(builder.toString()));
refreshText("√(" + builder.toString() + ")=\n" + result);
}
}
//檢查整個(gè)表達(dá)式
public boolean verifyExp(String exp){ //驗(yàn)證整個(gè)表達(dá)式是否合法
String lastNum="";
String[] sp=exp.split("\\+|-|×|÷"); //將操作數(shù)分割出來
char lastChar=exp.charAt(exp.length()-1); //獲得最后一個(gè)字符
lastNum=sp[sp.length-1]; //取得最后一位操作數(shù)
if(String.valueOf(lastChar).matches("\\+|-|×|÷")) //如果當(dāng)前符號(hào)為四則運(yùn)算符
{
lastNum="";
return exp.matches(".*(\\d[+-×÷])|.*(\\.[+-×÷])"); //驗(yàn)證最后的運(yùn)算符是否符合只有一個(gè)原則
}else{ //最后一位為運(yùn)算數(shù)
return lastNum.matches("^[-]?\\d*\\.?\\d*"); //驗(yàn)證最后一位運(yùn)算數(shù)是否合法
}
}
// 刷新文本顯示
private void refreshText(String text) {
showText = text;
tv_result.setText(showText);
}
// 清空并初始化
private void clear() {
builder.delete(0, builder.length());
showText="";
}
//基本每個(gè)出結(jié)果的按鈕都要執(zhí)行一次這個(gè)函數(shù)
public void resultCheck(){ //運(yùn)算結(jié)果檢查,有結(jié)果用結(jié)果,結(jié)果不為數(shù)字進(jìn)行處理
if(result!=0){ //如果結(jié)果不為0,則按照結(jié)果進(jìn)行運(yùn)算
String res=String.valueOf(result);
if(res.matches("^[-]?\\d*\\.?\\d*")){ //若為浮點(diǎn)數(shù)字
clear();
builder.append(result);
result=0; //結(jié)果不清零,檢查的時(shí)候就會(huì)一直重復(fù)放入結(jié)果
}else{ //若結(jié)果為字母,分母為0會(huì)返回Infinity,以及負(fù)數(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ù)字隊(duì)列,
private static final Queue<String> queOp = new ArrayDeque<>(); //符號(hào)隊(duì)列
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";
//本算法似乎不支持符號(hào)在前面,目前算法已經(jīng)改進(jìn)
//處理運(yùn)算符在式子最后
if (exp.matches(".*[\\+\\-×÷]")) {
exp = exp.substring(0, exp.length() - 1);
}
String[] sp; //存放分割數(shù)組
//運(yùn)算符在式子最前面
if (exp.matches("[\\+\\-×÷].*")) {
String fistElem=exp.substring(0,1); //截取首個(gè)字符
exp=exp.substring(1); //舍去首個(gè)字符
//分割字符,提取數(shù)字
sp = exp.split("\\+|-|×|÷");
if(fistElem.equals("-")){ //首個(gè)字符為負(fù)號(hào)
sp[0]="-"+sp[0]; //添加負(fù)號(hào)
}
}else{ //沒有符號(hào)在前
sp = exp.split("\\+|-|×|÷");
}
//之前直接分割字符會(huì)導(dǎo)致,數(shù)組第一位為空,導(dǎo)致程序無法運(yùn)行
for (int i = sp.length - 1; i >= 0; i--) {
if (sp[i].equals(".")) {
st.push(0.0); //替換點(diǎn)號(hào)
} 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());
//運(yùn)算降級(jí)序列化
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());
}
}
//正常運(yùn)算
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)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android開發(fā)實(shí)現(xiàn)的簡單計(jì)算器功能【附完整demo源碼下載】
- android計(jì)算器簡單實(shí)現(xiàn)代碼
- 簡單實(shí)現(xiàn)Android計(jì)算器功能
- Android實(shí)戰(zhàn)教程第一篇之最簡單的計(jì)算器
- Android計(jì)算器簡單邏輯實(shí)現(xiàn)實(shí)例分享
- Android開發(fā)學(xué)習(xí)實(shí)現(xiàn)簡單計(jì)算器
- Android實(shí)現(xiàn)簡單加法計(jì)算器
- Android簡單實(shí)現(xiàn)計(jì)算器功能
- Android實(shí)現(xiàn)簡單計(jì)算器
- Android實(shí)戰(zhàn)項(xiàng)目之實(shí)現(xiàn)一個(gè)簡單計(jì)算器
相關(guān)文章
Android沉浸式狀態(tài)欄的實(shí)現(xiàn)代碼
這篇文章主要為大家詳細(xì)介紹了Android沉浸式狀態(tài)欄的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09
Android編程獲取手機(jī)后臺(tái)運(yùn)行服務(wù)的方法
這篇文章主要介紹了Android編程獲取手機(jī)后臺(tái)運(yùn)行服務(wù)的方法,涉及Android針對(duì)系統(tǒng)服務(wù)的相關(guān)操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-12-12
Android錄音功能的實(shí)現(xiàn)以及踩坑實(shí)戰(zhàn)記錄
在Android 開發(fā)過程中,有些功能是通用的,或者是多個(gè)業(yè)務(wù)方都需要使用的,下面這篇文章主要給大家介紹了關(guān)于Android錄音功能的實(shí)現(xiàn)以及踩坑的相關(guān)資料,需要的朋友可以參考下2022-06-06
Android開發(fā)之獲取LayoutInflater對(duì)象的方法總結(jié)
這篇文章主要介紹了Android開發(fā)之獲取LayoutInflater對(duì)象的方法,結(jié)合實(shí)例形式總結(jié)分析了Android獲取LayoutInflater對(duì)象的常用技巧,需要的朋友可以參考下2016-02-02
Android 自定義可拖拽View界面渲染刷新后不會(huì)自動(dòng)回到起始位置
這篇文章主要介紹了Android 自定義可拖拽View界面渲染刷新后不會(huì)自動(dòng)回到起始位置的實(shí)現(xiàn)代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-02-02
Android?獲取IP和UA實(shí)現(xiàn)示例詳解
這篇文章主要為大家介紹了Android?獲取IP和UA實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
Android4.0.x Home鍵事件攔截監(jiān)聽的方法
這篇文章主要介紹了Android4.0.x Home鍵事件攔截監(jiān)聽的方法,對(duì)比分析了2.3.x的實(shí)現(xiàn)方法,分析了4.0.x實(shí)現(xiàn)Home鍵事件攔截監(jiān)聽的相關(guān)技巧,需要的朋友可以參考下2016-02-02

