Android计算器—入门

作者:黑衣侠客


一.前言

这是我写的第一个App,利用的是《安卓第一行代码》第三章,UI控件的一些知识,然后整体结构综合了一些CSDN博客和简书上的一些著作,同样,在写Android计算器,我将近花费了一周的时间,研究一些层次结构,UI控件,以及一些需要用到但书中没有的一些功能关键字和数据结构,然后,在写Android计算器的时候,Android studio总会出现一些不知名的错误,然后一点一点的查和修改。另外,如果电脑配置不高的话,用虚拟机的话,会编译运行的特别慢,所以,建议大家多用下真机测试,特别快。接下来,我将会为大家分享我做计算器的基本步骤。

二.准备

1.编译器:Android Studio(有很多功能待我们发现)

2.Android计算器所需知识:
1.在这之前有简单的Java基础,了解Java一些关键字的使用
2.对《第一行代码》的第三章(UI开发大致掌握,学会运用)
3.对计算器计算的算法大致掌握(中缀表达式转后缀表达式,后缀表达式的运算)
4.后缀表达式需要用到的关键字BigDecimal
3.学会使用百度,谷歌,浏览一些必要的资料
当然也可以去CSDN官网去看一些别人所写的文章,进行学习,然后好好看一遍别人写的代码,仔细研究一下,你会收获很多知识的。
4.大致了解Android Studio的基本功能
三.实现控件的一些分布,并且实现渲染

这是我用真机侧试,渲染后的结果。


代码部分

**在这里我采用的是百分比布局,但是百分比是新增布局,所以必须自己动手增加相应的依赖。在Android Studio中打开app的build.grade文件,在dependencies闭包中添加这样的代码

其中的29.0.1根据自己的版本填写,例如我的是:

注意:填写位置的图标为 :

添加之后,编辑面板顶部会出现一行提示,点击Sync now 稍等片刻即可

1.button的周边边框

**因为Android对button不能通过对属性的更改进行变化,所以我们需要在内部进行修改,创建一个图片文件,设置背景色以及边框的宽度和颜色,然后把button的背景属性设置为图片

  • 首先在Android Studio中在app/src/main/drawable文件夹中创建一个Drawable resource file
  • 之后再弹出的窗口设置文件名,文件名随意,我设置的是shape_white
  • 因为我创建了三种颜色,所以就创建了3个文件,另外两个文件名分别是:shape_blue,shape_yellow(当时加减乘除都用的是黄色,后来改用灰色的了,之后文件名就懒的改了~~)
  • 下面是我这个文件的内容:
//不过下面代码的注释最好删掉
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"><solidandroid:color="#ffffff"/>//设置背景颜色(白色)<strokeandroid:width="0.01dp"//设置边框的宽度android:color="#ccc0c0c0"/>//设置边框的颜色
</shape>

剩下的灰色和蓝色只需要改变背景颜色就好了

android:color="#f0ffff"/>//蓝色
android:color="#fff0f0f0"/>//银灰色
android:color="#ff0fff"/>//紫色

这里我就不依次介绍颜色属性了


之后
在你布局的文件(例如app/src/main/res/layout/activity_main.xml)中,对需要显示的边框的button中添加设置背景这行代码

<Buttonandroid:id="@+id/button0"android:background="@drawable/click_white"//设置button背景颜色/>

2.实现Button的点击变色功能

我的计算器中,点击按键时变为紫色

  • 首先在Android Studio(app/src/main/res/drawable)文件夹中创建一个Drawable resource file,之后创建文件名,我的是click_purple
  • 然后把代码修改为:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:drawable="@drawable/shape_purple_bg"//设置点击之后的颜色android:state_enabled="true"android:state_pressed="true"/>//当button被点击时<item android:drawable="@drawable/shape_white_bg"//设置背景(点击之前的颜色)android:state_enabled="true"android:state_pressed="false"/>//当未被点击时
</selector>

这串代码的含义是:由白色变为紫色
然后说明一下这个代码需要两种颜色文件,刚刚我们已经创建了一个,再创建一个即可
例如:创建紫色的颜色文件

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"><solidandroid:color="#ff0fff"/>//紫色<strokeandroid:width="0.01dp"android:color="#ccc0c0c0"/>
</shape>

3.字体自适应显示框而改变大小

例如:
------------
添加一串代码

//同样添加一串代码
<TextViewandroid:"@+id/text_view"app:autoSizeTextType="uniform"//字体自适应功能app:layout_heightPercent="25%"//用百分比调节显示模块的高度app:layout_widthPercent="100%"//用百分比调节显示模块的宽度/>
  • 但是这种做法同样存在缺点,就是他的输入框有多大,他显示的字体就有多大,所以这就需要我们对他进行一些限制,限制最大字体,最小字体,和每次变化的字体大小

具体一些控件的说明就说到这儿了,接下来,我们看一下控件部分的代码
activity_main.xml

<androidx.percentlayout.widget.PercentRelativeLayout//百分比布局,一定要看清,因为还有一个androidx...中也带Percentxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"><Buttonandroid:id="@+id/buttonc"android:layout_width="0dp"//没有具体作用,因为运用百分比布局,这里的0dp是一种规范android:layout_height="0dp"android:layout_alignParentLeft="true"//控制控件的位置android:layout_alignParentBottom="true"//控制控件的位置android:layout_gravity="bottom"android:text="C"//控件显示的名称android:textSize="40sp"//控件名称字体大小app:layout_heightPercent="14%"//控件高度占屏幕高度的百分比app:layout_widthPercent="25%"//控件宽度占屏幕宽度的百分比android:background="@drawable/click_purple_blue"/>//点击事件的颜色(点击之前是蓝色,点击之后是紫色)<Buttonandroid:id="@+id/button1"android:textSize="40sp"android:layout_width="0dp"android:layout_height="0dp"app:layout_heightPercent="14%"app:layout_widthPercent="25%"android:layout_above="@id/buttonc"android:text="1"android:background="@drawable/click_purple_white"/><Buttonandroid:id="@+id/buttond"android:layout_width="0dp"android:layout_height="0dp"android:layout_alignParentRight="true"android:layout_alignParentBottom="true"android:text="="android:textSize="40sp"app:layout_heightPercent="14%"app:layout_widthPercent="25%"android:background="@drawable/click_purple_blue"/><Buttonandroid:id="@+id/button0"android:layout_width="0dp"android:layout_height="0dp"android:layout_toRightOf="@id/buttonc"android:layout_alignParentBottom="true"android:text="0"android:textSize="40sp"app:layout_heightPercent="14%"app:layout_widthPercent="25%"android:background="@drawable/click_purple_white"/><Buttonandroid:id="@+id/buttonDot"android:layout_width="0dp"android:layout_height="0dp"android:layout_toRightOf="@id/button0"android:layout_alignParentBottom="true"android:text="."android:textSize="40sp"app:layout_heightPercent="14%"app:layout_widthPercent="25%"android:background="@drawable/click_purple_blue"/><Buttonandroid:id="@+id/button2"android:textSize="40sp"android:layout_width="0dp"android:layout_height="0dp"app:layout_heightPercent="14%"app:layout_widthPercent="25%"android:layout_toRightOf="@id/button1"android:layout_above="@id/button0"android:text="2"android:background="@drawable/click_purple_white"/><Buttonandroid:id="@+id/button3"android:textSize="40sp"android:layout_width="0dp"android:layout_height="0dp"app:layout_heightPercent="14%"app:layout_widthPercent="25%"android:layout_toRightOf="@id/button2"android:layout_above="@id/buttonDot"android:text="3"android:background="@drawable/click_purple_white"/><Buttonandroid:id="@+id/button4"android:layout_height="0dp"android:layout_width="0dp"app:layout_heightPercent="14%"app:layout_widthPercent="25%"android:text="4"android:textSize="40sp"android:layout_above="@id/button1"android:background="@drawable/click_purple_white"/><Buttonandroid:id="@+id/button5"android:layout_height="0dp"android:layout_width="0dp"app:layout_heightPercent="14%"app:layout_widthPercent="25%"android:text="5"android:textSize="40sp"android:layout_above="@id/button2"android:layout_toRightOf="@id/button4"android:background="@drawable/click_purple_white"/><Buttonandroid:id="@+id/button6"android:layout_height="0dp"android:layout_width="0dp"app:layout_heightPercent="14%"app:layout_widthPercent="25%"android:text="6"android:textSize="40sp"android:layout_above="@id/button3"android:layout_toRightOf="@id/button5"android:background="@drawable/click_purple_white"/><Buttonandroid:id="@+id/buttonj"android:layout_height="0dp"android:layout_width="0dp"app:layout_heightPercent="14%"app:layout_widthPercent="25%"android:text="+"android:textSize="40sp"android:layout_above="@id/buttonchenG"android:layout_toRightOf="@id/button6"android:background="@drawable/click_purple_yellow"/><Buttonandroid:id="@+id/buttonchenG"android:layout_height="0dp"android:layout_width="0dp"app:layout_heightPercent="14%"app:layout_widthPercent="25%"android:text="*"android:textSize="40sp"android:layout_above="@id/buttond"android:layout_toRightOf="@id/button3"android:background="@drawable/click_purple_yellow"/><Buttonandroid:id="@+id/button7"android:layout_height="0dp"android:layout_width="0dp"app:layout_heightPercent="14%"app:layout_widthPercent="25%"android:text="7"android:textSize="40sp"android:layout_above="@id/button4"android:background="@drawable/click_purple_white"/><Buttonandroid:id="@+id/button8"android:layout_height="0dp"android:layout_width="0dp"app:layout_heightPercent="14%"app:layout_widthPercent="25%"android:text="8"android:textSize="40sp"android:layout_above="@id/button5"android:layout_toRightOf="@id/button7"android:background="@drawable/click_purple_white"/><Buttonandroid:id="@+id/button9"android:layout_height="0dp"android:layout_width="0dp"app:layout_heightPercent="14%"app:layout_widthPercent="25%"android:text="9"android:textSize="40sp"android:layout_above="@id/button6"android:layout_toRightOf="@id/button8"android:background="@drawable/click_purple_white"/><Buttonandroid:id="@+id/buttonjian"android:layout_height="0dp"android:layout_width="0dp"app:layout_heightPercent="14%"app:layout_widthPercent="25%"android:text="-"android:textSize="40sp"android:layout_above="@id/buttonj"android:layout_toRightOf="@id/button9"android:background="@drawable/click_purple_yellow"/><Button//左括号android:id="@+id/buttonzuokuo"android:layout_height="0dp"android:layout_width="0dp"app:layout_heightPercent="14%"app:layout_widthPercent="25%"android:text="("android:textSize="40sp"android:layout_above="@id/button7"android:background="@drawable/click_purple_blue"/><Button//右括号android:id="@+id/buttonyoukuo"android:layout_width="0dp"android:layout_height="0dp"android:text=")"android:layout_toRightOf="@id/buttonc"android:layout_above="@id/button8"android:textSize="40sp"app:layout_heightPercent="14%"app:layout_widthPercent="25%"android:background="@drawable/click_purple_blue"/><Button//除号android:id="@+id/buttonchufa"android:layout_width="0dp"android:layout_height="0dp"android:text="/"android:layout_toRightOf="@id/buttonyoukuo"android:layout_above="@id/button9"android:textSize="40sp"app:layout_heightPercent="14%"app:layout_widthPercent="25%"android:background="@drawable/click_purple_yellow"/><Button//删除键android:id="@+id/buttons"android:layout_width="0dp"android:layout_height="0dp"android:text="Del"android:layout_toRightOf="@id/buttonchufa"android:layout_above="@id/buttonjian"android:textSize="30sp"app:layout_heightPercent="14%"app:layout_widthPercent="25%"android:background="@drawable/click_purple_blue"/><TextView//显示android:id="@+id/text_view"android:background="#FAFFF0"//背景颜色android:autoSizeTextType="uniform"//字体自适应app:autoSizeMaxTextSize="80sp"//规定最大字体app:autoSizeMinTextSize="20sp"//规定最小字体app:autoSizeStepGranularity="4sp"//每次字体改变的大小android:layout_height="0dp"//规范android:layout_width="0dp"//规范android:textSize="40sp"//字体最初大小app:layout_heightPercent="30%"//显示的高度的百分比app:layout_widthPercent="100%"/></androidx.percentlayout.widget.PercentRelativeLayout>

4.活动代码的异常处理

  • 1.在开始输入时,输入“-”时,代表负号,此时,屏幕显示的应该是“(-”。
  • 2.对于“)”这个符号来说,在运算时,需要先查明左右括号数是否相等,若不相等应该报错
  • 3.当输出结果有问题时,应该报错,输出Error
  • 4.如果减号前面有加减乘除号时,该减号系统内部,应该当做负号处理
  • 5.还有就是小数点的一些问题,例如前面自动补零,等等
  • 6.还有就是删除负号时,点击一下del,删除两个
    字符,这个需要加一个判断,在加判断时注意一下空间分配问题
  • 7.当然,还有很多,就不依次列举了

MainActivity代码

package com.example.calculation;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private TextView textView;private StringBuffer sb=new StringBuffer();private StringBuffer str=new StringBuffer();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//定义控件Button button0=findViewById(R.id.button0);Button button1=findViewById(R.id.button1);Button button2=findViewById(R.id.button2);Button button3=findViewById(R.id.button3);Button button4=findViewById(R.id.button4);Button button5=findViewById(R.id.button5);Button button6=findViewById(R.id.button6);Button button7=findViewById(R.id.button7);Button button8=findViewById(R.id.button8);Button button9=findViewById(R.id.button9);Button buttonj=findViewById(R.id.buttonj);Button buttonjian=findViewById(R.id.buttonjian);Button buttonzuokuo=findViewById(R.id.buttonzuokuo);Button buttonyoukuo=findViewById(R.id.buttonyoukuo);Button buttonchenG=findViewById(R.id.buttonchenG);Button buttonc=findViewById(R.id.buttonc);Button buttond=findViewById(R.id.buttond);Button buttonDot=findViewById(R.id.buttonDot);Button buttons=findViewById(R.id.buttons);Button buttonchufa=findViewById(R.id.buttonchufa);textView =findViewById(R.id.text_view);button0.setOnClickListener(this);button1.setOnClickListener(this);button2.setOnClickListener(this);button3.setOnClickListener(this);button4.setOnClickListener(this);button5.setOnClickListener(this);button6.setOnClickListener(this);button7.setOnClickListener(this);button8.setOnClickListener(this);button9.setOnClickListener(this);buttonc.setOnClickListener(this);buttonchufa.setOnClickListener(this);buttonchenG.setOnClickListener(this);buttonjian.setOnClickListener(this);buttonj.setOnClickListener(this);buttond.setOnClickListener(this);buttonDot.setOnClickListener(this);buttons.setOnClickListener(this);buttonzuokuo.setOnClickListener(this);buttonyoukuo.setOnClickListener(this);}private int count_negative=0;private boolean equals=false;private int count_bracket_left=0;//左括号个数标记private int count_bracket_right=0;//右括号个数标记private int a=0;//删除时当做记录的指针@Overridepublic void onClick(View view){switch(view.getId()){case R.id.button0:if(equals){sb =sb.delete(0,sb.length());equals=false;}if(sb.length()==0){sb.append("0");}else{if(sb.charAt(sb.length()-1)==')'){///如果前面是右括号那么在0前补充乘号sb.append("*0");}else{sb.append("0");}}textView.setText(sb.toString());break;case R.id.button1:if(equals){sb=sb.delete(0,sb.length());equals=false;}if(sb.length()==0){sb.append("1");}else{if(sb.charAt(sb.length()-1)==')'){sb.append("*1");}else{sb.append("1");}}textView.setText(sb.toString());break;case R.id.button2:if(equals){sb=sb.delete(0,sb.length());equals=false;}if(sb.length()==0){sb.append("2");}else{if(sb.charAt(sb.length()-1)==')'){sb.append("*2");}else{sb.append("2");}}textView.setText(sb.toString());break;case R.id.button3:if(equals){sb=sb.delete(0,sb.length());equals=false;}if(sb.length()==0){sb.append("3");}else{if(sb.charAt(sb.length()-1)==')'){sb.append("*3");}else{sb.append("3");}}textView.setText(sb.toString());break;case R.id.button4:if(equals){sb=sb.delete(0,sb.length());equals=false;}if(sb.length()==0){sb.append("4");}else{if(sb.charAt(sb.length()-1)==')'){sb.append("*4");}else{sb.append("4");}}textView.setText(sb.toString());break;case R.id.button5:if(equals){sb=sb.delete(0,sb.length());equals=false;}if(sb.length()==0){sb.append("5");}else{if(sb.charAt(sb.length()-1)==')'){sb.append("*5");}else{sb.append("5");}}textView.setText(sb.toString());break;case R.id.button6:if(equals){sb=sb.delete(0,sb.length());equals=false;}if(sb.length()==0){sb.append("6");}else{if(sb.charAt(sb.length()-1)==')'){sb.append("*6");}else{sb.append("6");}}textView.setText(sb.toString());break;case R.id.button7:if(equals){sb=sb.delete(0,sb.length());equals=false;}if(sb.length()==0){sb.append("7");}else{if(sb.charAt(sb.length()-1)==')'){sb.append("*7");}else{sb.append("7");}}textView.setText(sb.toString());break;case R.id.button8:if(equals){sb=sb.delete(0,sb.length());equals=false;}if(sb.length()==0){sb.append("8");}else{if(sb.charAt(sb.length()-1)==')'){sb.append("*8");}else{sb.append("8");}}textView.setText(sb.toString());break;case R.id.button9:if(equals){sb=sb.delete(0,sb.length());equals=false;}if(sb.length()==0){sb.append("9");}else{if(sb.charAt(sb.length()-1)==')'){sb.append("*9");}else{sb.append("9");}}textView.setText(sb.toString());break;case R.id.butif(equals){equals=false;}if(sb.length()!=0&&a==0){if(sb.charAt(sb.length()-1)=='-'&&sb.charAt(sb.length()-2)=='('||sb.charAt(sb.length()-1)=='.'&&sb.charAt(sb.length()-2)=='0'){sb=sb.deleteCharAt(sb.length()-1);sb=sb.deleteCharAt(sb.length()-1);}else{sb=sb.deleteCharAt(sb.length()-1);}}else if(sb.length()!=0&&a==1){sb=sb.delete(0,sb.length());}textView.setText(sb.toString());a=0;break;case R.id.buttonc:if(equals){equals=false;}sb=sb.delete(0,sb.length());textView.setText(sb.toString());break;case R.id.buttonzuokuo:if(equals){equals=false;}if(sb.length()>0&&(sb.charAt(sb.length()-1)>='0'&&sb.charAt(sb.length()-1)<='9')){sb=sb.append("*(");}if(sb.length()==0){sb.append("(");}if(sb.length()>0&&(sb.charAt(sb.length()-1)=='*'||sb.charAt(sb.length()-1)=='/'||sb.charAt(sb.length()-1)=='+'||sb.charAt(sb.length()-1)=='-')){sb=sb.append("(");}textView.setText(sb.toString());break;case R.id.buttonyoukuo:if(equals){equals=false;}int count_num=0;int Sum=0;int num=0;count_bracket_left=count_bracket_right=0;if(sb.length()!=0){for(int i=sb.length()-1;i>=0;i--){if(count_bracket_left==0&&(sb.charAt(i)>='0'&&sb.charAt(i)<='9')){count_num++;}if(sb.charAt(i)=='('){count_bracket_left++;}if(sb.charAt(i)==')'){count_bracket_right++;}}if((count_bracket_left>count_bracket_right)&&count_num>0){if(sb.charAt(sb.length()-1)!='-'&&sb.charAt(sb.length()-1)!='+'&&sb.charAt(sb.length()-1)!='*'&&sb.charAt(sb.length()-1)!='/'){sb.append(")");}}}textView.setText(sb.toString());break;case R.id.buttonj:if(equals){equals=false;}if(sb.length()!=0){if(sb.charAt(sb.length()-1)>='0'&&sb.charAt(sb.length()-1)<='9'||sb.charAt(sb.length()-1)=='.'){if(sb.charAt(sb.length()-1)>='0'&&sb.charAt(sb.length()-1)<='9'){sb.append("+");}if(sb.charAt(sb.length()-1)=='.'){sb.append("0+");}}if(sb.charAt(sb.length()-1)==')'){sb.append("+");}}textView.setText(sb.toString());break;case R.id.buttonjian:if(equals){equals=false;}if(sb.length()!=0){if(sb.charAt(sb.length()-1)>='0'&&sb.charAt(sb.length()-1)<='9'||sb.charAt(sb.length()-1)=='.'){if(sb.charAt(sb.length()-1)>='0'&&sb.charAt(sb.length()-1)<='9'){sb.append("-");}if(sb.charAt(sb.length()-1)=='.'){sb.append("0-");}}else if(sb.charAt(sb.length()-1)==')'){sb.append("-");}else if(sb.charAt(sb.length()-1)=='('){sb.append("(-");}else if(sb.charAt(sb.length()-1)=='+'||sb.charAt(sb.length()-1)=='-'||sb.charAt(sb.length()-1)=='*'||sb.charAt(sb.length()-1)=='/'){sb.append("(-");}}else{sb.append("(-");}textView.setText(sb.toString());break;case R.id.buttonchenG:if(equals){equals=false;}if(sb.length()!=0){if(sb.charAt(sb.length()-1)>='0'&&sb.charAt(sb.length()-1)<='9'||sb.charAt(sb.length()-1)=='.'){if(sb.charAt(sb.length()-1)>='0'&&sb.charAt(sb.length()-1)<='9'){sb.append("*");}if(sb.charAt(sb.length()-1)=='.'){sb.append("0*");}}if(sb.charAt(sb.length()-1)==')'){sb.append("*");}}textView.setText(sb.toString());break;case R.id.buttonchufa:if(equals){equals=false;}if(sb.length()!=0){if(sb.charAt(sb.length()-1)>='0'&&sb.charAt(sb.length()-1)<='9'||sb.charAt(sb.length()-1)=='.'){if(sb.charAt(sb.length()-1)>='0'&&sb.charAt(sb.length()-1)<='9'){sb.append("/");}if(sb.charAt(sb.length()-1)=='.'){sb.append("0/");}}if(sb.charAt(sb.length()-1)==')'){sb.append("/");}}textView.setText(sb.toString());break;case R.id.buttonDot:int apps=0;if(equals){equals=false;}if(sb.length()!=0){if(sb.charAt(sb.length()-1)>='0'&&sb.charAt(sb.length()-1)<='9'){for(int i=sb.length()-2;i>=0;i--){if(sb.charAt(i)=='.'){apps=1;break;}else if(sb.charAt(i)=='('||sb.charAt(i)=='+'||sb.charAt(i)=='-'||sb.charAt(i)=='*'||sb.charAt(i)=='/'){break;}}if(apps==0){sb.append(".");}}if(sb.charAt(sb.length()-1)=='('||sb.charAt(sb.length()-1)==')'){if(sb.charAt(sb.length()-1)==')'){sb.append("*0.");}else{sb.append("0.");}}if(sb.charAt(sb.length()-1)=='*'||sb.charAt(sb.length()-1)=='/'||sb.charAt(sb.length()-1)=='+'||sb.charAt(sb.length()-1)=='-'){sb.append("0.");}}else{sb.append("0.");}textView.setText(sb.toString());break;case R.id.buttond:int count_left=0;int count_right=0;if(equals){equals=false;}if(sb.length()!=0){for(int i=sb.length()-1;i>=0;i--){if(sb.charAt(i)==')'){count_right++;}if(sb.charAt(i)=='('){count_left++;}}if(count_left!=count_right){Toast.makeText(MainActivity.this, "请注意括号匹配!!!", Toast.LENGTH_SHORT).show();}if(count_left==count_right&&(sb.charAt(sb.length()-1)>='0'&&sb.charAt(sb.length()-1)<='9')||sb.charAt(sb.length()-1)==')'){try{textView.setText(InfixToSuffix.Cal(InfixToSuffix.Suffix(sb)));a=1;//利用类名两次调用静态方法,将后缀表达式的结果输出在屏幕上sb=sb.delete(0,sb.length());sb.append(textView.getText().toString());}catch(Exception e){textView.setText("Error!!!");sb=sb.delete(0,sb.length());}}}break;default:break;}}
}//如果等号前面是小数点的话,就在小数点后补0

5.计算器算法

1.中缀表达式转后缀表达式

2.后缀表达式计算

另外后续用代码实现时还是有些困难,需要慢慢用心看


6.计算的具体代码

在MainActivity同一个包下创建class文件,命名为InfixToSuffix,将其作为计算方法
代码如下:

package com.example.calculation;
import android.util.Log;import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;public class InfixToSuffix {//将中缀表达式转化为后缀表达式public static ArrayList Suffix(StringBuffer str) {for (int i = 1; i < str.length(); i++) {//在负数的负号前添加一个“0”if (str.charAt(i) == '-' && str.charAt(i - 1) == '(') {//识别负数str.insert(i, '0');}}StringBuilder temp = new StringBuilder();List<String> list = new ArrayList<>();ArrayList<String> result = new ArrayList<>();//将中缀表达式转换后的后缀表达式储存在result数组中for (int i = 0; i < str.length(); i++) {//遍历整个中缀表达式if ((str.charAt(i) >= '0' && str.charAt(i) <= '9') || str.charAt(i) == '.') {//检测数字和小数点if (str.charAt(i) == '.' && temp.length() == 0) {temp.append(0);temp.append(str.charAt(i));} else {temp.append(str.charAt(i));}if (i == str.length() - 1) {//该步骤的作用是取决于上一步的else中的,例如:假设中缀表达式没有小数点时,那么最后一位如果为数字,就先执行else里的命令,然后将temp全部输入到list里list.add(temp.toString());//将temp中的全部添加到list中}} else {//符号进到这里if (temp.length() != 0)list.add(temp.toString());list.add(String.valueOf((str.charAt(i))));//将StringBuffer型的str.charAt(i)转化为String类型的,添加到list数组中temp.delete(0, temp.length());//temp清空}}//以上步骤就是将StringBuffe类型转换为String类型,中缀表达式不变for (String aList : list) {System.out.println(aList + "");}System.out.println();Stack<String> stack = new Stack<>();Map<Character, Integer> map = new HashMap<>();//Character代表字符类,表示对单个字符进行操作,其基本数据类型为char。//Integer为复杂数据类型,是int的封装类,其初始值为nullmap.put('(', 2);//定义符号的优先级map.put(')', 2);map.put('*', 1);map.put('/', 1);map.put('+', 0);map.put('-', 0);for (String s : list) {if (s.equals("*") || s.equals("/") || s.equals("+") || s.equals("-") || s.equals("(") || s.equals(")")) {if (stack.size() == 0) {stack.push(s);//如果当前栈内没有元素,让符号直接进栈} else {if (s.equals(")")) {if (!stack.empty()) {while (!stack.peek().equals("(")) {result.add(stack.pop());if (stack.empty()) {break;}}if (!stack.empty()) {if (stack.peek().equals("("))//查看栈顶对象而不移除它stack.pop();}}} else {if (stack.peek().charAt(0) != '(') {if (map.get(s.charAt(0)) > map.get(stack.peek().charAt(0))) {stack.push(s);} else {while ((map.get(s.charAt(0)) <= map.get(stack.peek().charAt(0))) && !stack.empty()) {result.add(stack.pop());if (stack.empty()) {break;}if (stack.peek().equals("(")) {break;}}stack.push(s);}} else {stack.push(s);}}}} else {result.add(s);}}while (!stack.empty()) {result.add(stack.pop());}return result;}//将得到的后缀表达式进行运算public static String Cal(ArrayList arrayList) {int length = arrayList.size();String[] arr = new String[length];for (int i = 0; i < arrayList.size(); i++) {arr[i] = (String) arrayList.get(i);}List<String> list = new ArrayList<>();for (String anArr : arr) {int size = list.size();switch (anArr) {case "+":BigDecimal a = new BigDecimal(list.remove(size - 2)).add(new BigDecimal(list.remove(size - 2)));list.add(a.stripTrailingZeros().toString());//用科学计数法向list中输入字符串break;case "-":BigDecimal b = new BigDecimal(list.remove(size - 2)).subtract(new BigDecimal(list.remove(size - 2)));list.add(b.stripTrailingZeros().toString());break;case "*":BigDecimal c = new BigDecimal(list.remove(size - 2)).multiply(new BigDecimal(list.remove(size - 2)));list.add(c.stripTrailingZeros().toString());break;case "/":BigDecimal d = new BigDecimal(list.remove(size - 2)).divide(new BigDecimal(list.remove(size - 2)), 10, BigDecimal.ROUND_HALF_UP);list.add(d.stripTrailingZeros().toString());break;default:list.add(anArr);break;}}if (list.size() == 1) {if (list.get(0).length() < 30) {BigDecimal bd = new BigDecimal(list.get(0));return bd.toPlainString();} else {double d = Double.valueOf(list.get(0));return String.valueOf(d);}} else {return "运算失败";}}
}

Android计算器——入门相关推荐

  1. Android 渗透测试学习手册 第一章 Android 安全入门

    第一章 Android 安全入门 作者:Aditya Gupta 译者:飞龙 协议:CC BY-NC-SA 4.0 Android 是当今最流行的智能手机操作系统之一. 随着人气的增加,它存在很多安全 ...

  2. 《Android 开发入门与实战(第二版)》——6.6节配置改变

    本节书摘来自异步社区<Android 开发入门与实战(第二版)>一书中的第6章,第6.6节配置改变,作者eoe移动开发者社区 组编 , 姚尚朗 , 靳岩,更多章节内容可以访问云栖社区&qu ...

  3. Android Volley入门到精通:初识Volley的基本用法

    1. Volley简介 我们平时在开发Android应用的时候不可避免地都需要用到网络技术,而多数情况下应用程序都会使用HTTP协议来发送和接收网络数据.Android系统中主要提供了两种方式来进行H ...

  4. android+studio入门指南+pdf,android+studio使用指南v0.1.pdf

    androidstudio使用指南v0.1 <Android Studio入门指南>作者:毕小朋 博客:/wirelessqa Android Studio入门指南v0.1 作者:毕小朋 ...

  5. Android编译系统入门(二)

    Android.mk的使用方法 在上一篇Android编译系统入门(一)中我们只要介绍了Android系统使用make命令默认编译的依赖树是droid,而droid是一个伪目标,它有两个先决条件dro ...

  6. 《Delphi XE6 android 编程入门教程》推荐

    近5.6年已经没有看见关于delphi的新技术的书出来了(看来在国内delphi的使用量确实很低了), 高勇同学最近出了一本<Delphi XE6 android 编程入门教程>,上周刚拿 ...

  7. android 编辑9图片,Android基础入门教程——1.6 .9(九妹)图片怎么玩

    Android基础入门教程--1.6 .9(九妹)图片怎么玩 Android基础入门教程 1.本节引言: 可能有的一些疑问: 1.什么是.9图片? 答:图片后缀名前有.9的图片,如pic1.9.png ...

  8. android开发入门_Android开发入门

    android开发入门 Android is an open source, Linux-based mobile operating system. Android was developed by ...

  9. android 菜鸟面单打印_1.0 Android基础入门教程

    本教程于2015年7月开始撰写,耗时半年,总共148节,涵盖了Android基础入门的大部分知识,由于当时能力局限,虽已竭尽全力,但对于一些问题的分析难免有所纰漏,敬请读者海涵!IT技术更新换代很快, ...

  10. Hello, Android 快速入门

    Hello, Android Android 开发与 Xamarin 简介 在这两节指南中,我们将 (使用 Xamarin Studio或 Visual Studio)建立我们的第一个 Xamarin ...

最新文章

  1. 计算机研究生上课时间自由吗,计算机在职研究生面授班主要的上课时间安排是怎样的呢...
  2. 几行代码养只猫,心情瞬间好多了
  3. linux下使用sftp
  4. crontab wget命令定时执行thinkphp的控制器实现定时任务
  5. 在移动了用户数据时Android平台的路径设置
  6. linux基本知识学习
  7. mysql between 查询不出来_mysql的语句优化
  8. 简述container与container-fluid的区别
  9. XP下安装装SQL2000企业版本
  10. [ZJOI2008]骑士
  11. Postman 把response的值自动放到变量里
  12. 10个大数据思维原理,你了解多少?
  13. arm9有多少个寄存器
  14. 如何设置浏览器标签图标
  15. iscript脚本截取字符串
  16. 假定网络中的路由器B的路由表有如下的项目(这三列分别表示“目的网络”、“距离”和“下一跳路由器”):
  17. ### Cause: java.sql.SQLSyntaxErrorException: ORA-00903: 表名无效
  18. 利用动态二进制加密实现新型一句话木马之.NET篇(转)冰蝎
  19. python 在Windows下 用软回车换行
  20. C语言通过指针交换两个数

热门文章

  1. HTML5实现音频和视频嵌入,如何利用HTML5实现音频和视频嵌入的方法
  2. 用python扑克随机发牌_Python小应用之发扑克牌
  3. 小米pro15拆机_小米笔记本Pro 15增强版拆解:重新定义高质低价
  4. MarkDown编辑器----小书匠
  5. C#之使用RichTextBox 实现简单的txt编辑器
  6. 【CityEngine教程文档】---01 基础教程
  7. mysql的默认隔离等级_mysql 四种隔离级别
  8. 用Python爬了我的微信好友,他们是这样的...
  9. ubuntu18.04桌面美化及部分应用的安装
  10. 联盟链系列 - 中间CA颁发证书