Android Calculator - Introduction

Android Calculator - Introduction

Author: Knight in Black

I. Preface

This is the first App I wrote, using the third chapter of Android First Line Code, some knowledge of UI controls. Then the overall structure synthesizes some works on CSDN blogs and short books. Similarly, in writing Android calculators, I have spent nearly a week studying some hierarchies, UI controls, and one. Some functional keywords and data structures that need to be used but are not available in the book. Then, when writing an Android calculator, Android studio will always make some unknown mistakes, and then check and modify them bit by bit. In addition, if the computer configuration is not high, the use of virtual machines will compile and run very slowly, so it is recommended that you use more real machine testing, especially fast. Next, I will share with you the basic steps of making a calculator.

II. Preparation

1. Compiler: Android Studio (there are many functions to be found)

2. Knowledge required by Android calculator:
1. Before that, there was a simple Java foundation to understand the use of some Java keywords.
2. Chapter 3 of "First Line of Code" (UI development in general, learn to use)
3. Master the algorithm of calculator calculation (infix expression to suffix expression, operation of suffix expression)
4. Suffix expressions need to be used Key word BigDecimal
3. Learn to use Baidu, Google and browse some necessary information.
Of course, you can also go to the CSDN official website to see some articles written by others, to learn, and then look at the code written by others, carefully study, you will gain a lot of knowledge.
4. Understand the basic functions of Android Studio
3. Implementing some distribution of controls and rendering

This is the result of a real machine side test and rendering.

Code section

** Here I use the percentage layout, but the percentage is the new layout, so I have to increase the corresponding dependencies by myself. Open the build.grade file of app in Android Studio and add such code in dependencies closure

Among them, 29.0.1 is based on its own version. For example, mine is:

Note: The icon for filling in the position is as follows:

After adding, a line of prompts appears at the top of the editing panel. Just click Sync now and wait a moment.

1. The peripheral of button

** Because Android can't change buttons by changing attributes, we need to modify them internally, create an image file, set the background color and the width and color of the border, and then set the button's background attribute to a picture.

  • First create a Drawable resource file in the app/src/main/drawable folder in Android Studio
  • Then pop-up window set file name, file name arbitrary, I set shape_white
  • Because I created three colors, I created three files. The other two file names are shape_blue and shape_yellow.
  • Below is the content of my document:
//However, the comments in the following code are best deleted
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid
        android:color="#ffffff"/>//Set the background color (white)
    <stroke
        android:width="0.01dp"//Set the width of the border
        android:color="#ccc0c0c0"/>//Set the color of the border
</shape>

The rest of the gray and blue just need to change the background color.

android:color="#f0ffff"/>//blue
android:color="#fff0f0f0"/>//Silver gray
android:color="#ff0fff"/>//Violet

Here I will not introduce the color attributes in turn.

after
In your layout file (such as app/src/main/res/layout/activity_main.xml), add the line setting the background to the button of the border that needs to be displayed.

<Button
	android:id="@+id/button0"
	android:background="@drawable/click_white"//Set button background color
	/>

2. Implementing Button's Click-to-Color Function

In my calculator, when I click the button, it turns purple.

  • First create a Drawable resource file in the Android Studio (app/src/main/res/drawable) folder, and then create the file name. My name is click_purple.
  • Then change the code to:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/shape_purple_bg"//Set the color after clicking
        android:state_enabled="true"
        android:state_pressed="true"/>//When the button is clicked
    <item android:drawable="@drawable/shape_white_bg"//Set the background (color before clicking)
        android:state_enabled="true"
        android:state_pressed="false"/>//When not clicked
</selector>

The meaning of this code is: from white to purple
Then I'll show you that this code needs two color files. We just created one, and then we can create another one.
For example, create a purple color file

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

3. Adaptive font display box to change size

For example:
------------
Add a bunch of code

//Add a bunch of code as well
<TextView
	android:"@+id/text_view"
	app:autoSizeTextType="uniform"//Font Adaptive Function
	app:layout_heightPercent="25%"//Adjusting the Height of Display Module with Percentage
	app:layout_widthPercent="100%"//Adjusting the Width of Display Module by Percentage
	/>
  • But there are also drawbacks in this approach, that is, the size of his input box and the font he displays, so we need to restrict him to the maximum font, the smallest font, and the font size of each change.

Here's the description of some controls. Next, let's take a look at the code of the control part.
activity_main.xml

<androidx.percentlayout.widget.PercentRelativeLayout//Percentage layout, we must see clearly, because there is also an androidx... with Percent in it.
    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"//There is no specific effect, because using percentage layout, 0dp here is a specification
        android:layout_height="0dp"
        android:layout_alignParentLeft="true"//Control control position
        android:layout_alignParentBottom="true"//Control control position
        android:layout_gravity="bottom"
        android:text="C"//Name of control display
        android:textSize="40sp"//Control name font size
        app:layout_heightPercent="14%"//Control Height Percentage of Screen Height
        app:layout_widthPercent="25%"//Control width as a percentage of screen width
        android:background="@drawable/click_purple_blue"/>//Click on the color of the event (blue before clicking, purple after clicking)
    <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//Left parentheses
        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//Right parentheses
        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//Division sign
        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//Delete key
        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//display
        android:id="@+id/text_view"
        android:background="#FAFFF0"//background color
        android:autoSizeTextType="uniform"//Font Adaptation
        app:autoSizeMaxTextSize="80sp"//Maximum font size
        app:autoSizeMinTextSize="20sp"//Minimum font size
        app:autoSizeStepGranularity="4sp"//The size of each font change
        android:layout_height="0dp"//Standard
        android:layout_width="0dp"//Standard
        android:textSize="40sp"//Initial font size
        app:layout_heightPercent="30%"//Percentage of height displayed
	app:layout_widthPercent="100%"/>

</androidx.percentlayout.widget.PercentRelativeLayout>

4. Exception handling of active code

  • 1. At the beginning of the input, when the "-" is input, it represents a minus sign. At this time, the screen should display "(-).
  • 2. For the symbol ")", it is necessary to find out whether the left and right brackets are equal in operation, and if they are not equal, the error should be reported.
  • 3. When there is a problem with the output, the error should be reported and the Error should be output.
  • 4. If the minus sign is preceded by the plus, minus, multiply and divide sign, the minus sign system should be treated as a negative sign.
  • 5. There are also some problems with decimal points, such as automatic zero-filling in front, and so on.
  • 6. When deleting the negative sign, click on del and delete two.
    Character, this needs to add a judgment, when adding judgment, pay attention to the problem of space allocation
  • 7. Of course, there are many more, not listed in turn.

MainActivity code

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);
       //Define controls
        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;//Number of left parentheses
    private int count_bracket_right=0;//Number of right parentheses
    private int a=0;//Delete as a pointer to a record
    @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)==')'){/// If the preceding bracket is the right bracket, add the multiplication sign before 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, "Please pay attention to bracket matching!!!", 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;
                            //Using class names to call static methods twice, the results of suffix expressions are output to the screen.
                            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;
        }
    }
}//If the decimal point precedes the equal sign, add 0 after the decimal point.

5. Calculator algorithm

1.Infix expression to suffix expression

2.Suffix expression calculation

In addition, there are still some difficulties in the subsequent implementation of the code, which need to be slowly and carefully looked at.

6. Specific code for calculation

Create a class file named InfixToSuffix under the same package in MainActivity as a computational method
The code is as follows:

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 {
    //Converting infix expressions into suffix expressions
    public static ArrayList Suffix(StringBuffer str) {
        for (int i = 1; i < str.length(); i++) {//Add a "0" before the negative sign of the negative number
            if (str.charAt(i) == '-' && str.charAt(i - 1) == '(') {//Identify negative numbers
                str.insert(i, '0');
            }
        }
        StringBuilder temp = new StringBuilder();
        List<String> list = new ArrayList<>();
        ArrayList<String> result = new ArrayList<>();//Store the transformed suffix expression in the result array
        for (int i = 0; i < str.length(); i++) {//Traversing the entire infix expression
            if ((str.charAt(i) >= '0' && str.charAt(i) <= '9') || str.charAt(i) == '.') {//Detection of digits and decimal points
                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) {//The role of this step depends on the previous step in else, for example, assuming that the infix expression has no decimal point, then if the last digit is a number, first execute the command in else, and then input temp all into the list.
                    list.add(temp.toString());//Add all of temp to the list
                }
            } else {//Symbols come in here.
                if (temp.length() != 0)
                    list.add(temp.toString());
                list.add(String.valueOf((str.charAt(i))));//Convert str.charAt(i) of StringBuffer type to String type and add it to list array
                temp.delete(0, temp.length());//temp emptying
            }
        }//The above step is to convert the StringBuffe type to String type with the infix expression unchanged.
        for (String aList : list) {
            System.out.println(aList + "");
        }
        System.out.println();
        Stack<String> stack = new Stack<>();
        Map<Character, Integer> map = new HashMap<>();
        //Character represents a character class, representing the operation of a single character, and its basic data type is char.
        //Integer is a complex data type and an encapsulated class of int with an initial value of null
        map.put('(', 2);//Define the priority of symbols
        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);//If there are no elements in the current stack, let the symbols go directly into the stack
                } 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("("))//View the stack top object without removing it
                                    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;
    }

    //Operate the resulting suffix expression
    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());//Enter Strings into list with Scientific Counting Normal
                    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 "Operational failure";
        }
    }
}

Keywords: Android Java calculator xml

Added by deckrdx on Mon, 29 Jul 2019 16:49:20 +0300