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计算器——入门_第1张图片
这是我用真机侧试,渲染后的结果。


代码部分

**在这里我采用的是百分比布局,但是百分比是新增布局,所以必须自己动手增加相应的依赖。在Android Studio中打开app的build.grade文件,在dependencies闭包中添加这样的代码
在这里插入图片描述
其中的29.0.1根据自己的版本填写,例如我的是:
Android计算器——入门_第2张图片
注意:填写位置的图标为 :
Android计算器——入门_第3张图片
添加之后,编辑面板顶部会出现一行提示,点击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">    <solid        android:color="#ffffff"/>//设置背景颜色(白色)    <stroke        android: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">    <solid        android:color="#ff0fff"/>//紫色    <stroke        android:width="0.01dp"        android:color="#ccc0c0c0"/></shape>

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

例如:
Android计算器——入门_第4张图片 ------------Android计算器——入门_第5张图片
添加一串代码

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

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

<androidx.percentlayout.widget.PercentRelativeLayout//百分比布局,一定要看清,因为还有一个androidx...中也带Percent    xmlns: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">    <Button        android: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"/>//点击事件的颜色(点击之前是蓝色,点击之后是紫色)    <Button        android: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"/>    <Button        android: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"/>    <Button        android: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"/>    <Button        android: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"/>    <Button        android: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"/>    <Button        android: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"/>    <Button        android: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"/>    <Button        android: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"/>    <Button        android: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"/>    <Button        android: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"        />    <Button        android: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"        />    <Button        android: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"/>    <Button        android: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"/>    <Button        android: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"/>    <Button        android: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();    @Override    protected 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;//删除时当做记录的指针    @Override    public 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.but                if(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的封装类,其初始值为null        map.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 "运算失败";        }    }}

更多相关文章

  1. Android HAL 层框架分析以及代码示例
  2. Android init源代码分析(1)概要分析
  3. Android设备之间通过Wifi通信的示例代码
  4. Android ActionBar的源代码分析(三)
  5. Android代码开发性能指引
  6. Android源代码分析(三) MediaScanner源码分析(下)

随机推荐

  1. Android——启动过程详解
  2. Android 系统HAL 简介
  3. [Android--Tool]Android如何将他人的代码
  4. android 笔记 ---- 使用Hessian与Java服
  5. Android样式的开发:shape篇
  6. Android(安卓)multidex 使用 与 实现原理
  7. [置顶] 【电子书下载】《Android应用程序
  8. Android 中的Parcelable序列化对象
  9. Android SDK 2.3与Eclipse最新版开发环境
  10. Android权限安全(5)组件的android:export