Android第一个项目——计算器

前言

最近开始学习Android,用Android写了第一个小项目——计算器。用Android写计算器首先是要从UI做起,再到每个Button的点击事件,再到计算器的核心代码部分,就是中缀表达式转为后缀表达式,然后再用后缀表达式求值,最后就到改bug的时间了。

布局

从布局开始,我的计算器就算正式开始了。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >

    <include layout="@layout/button" />

    <TextView
        android:id="@+id/editText_1"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:layout_marginStart="10dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="10dp"
        android:autoSizeTextType="uniform"
        android:background="#00000000"
        android:focusable="true"
        android:gravity="end|bottom"
        android:maxLines="2"
        android:textSize="30dp"
        android:autoSizeMinTextSize="40sp"
        android:autoSizeMaxTextSize="100sp"
        android:ellipsize="marquee"
        />

</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="470dp"

    android:layout_alignParentBottom="true"
    >

    <Button
        android:id="@+id/button_1"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:layout_marginLeft="10dp"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="290dp"
        android:background="@drawable/back_button"
        android:text="1"
        android:textColor="#000000"
        android:textSize="20dp" />

    <Button
        android:id="@+id/button_2"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:layout_marginLeft="100dp"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="290dp"
        android:background="@drawable/back_button"
        android:text="2"
        android:textColor="#000000"
        android:textSize="20dp"/>

    <Button
        android:id="@+id/button_3"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:layout_alignParentBottom="true"
        android:layout_marginLeft="190dp"
        android:layout_marginBottom="288dp"
        android:background="@drawable/back_button"
        android:text="3"
        android:textColor="#000000"
        android:textSize="20dp" />

    <Button
        android:id="@+id/button_4"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:text="4"
        android:textColor="#000000"
        android:layout_alignParentBottom="true"
        android:background="@drawable/back_button"
        android:layout_marginBottom="200dp"
        android:layout_marginLeft="10dp"
        android:textSize="20dp"/>

    <Button
        android:id="@+id/button_5"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:text="5"
        android:textColor="#000000"
        android:layout_alignParentBottom="true"
        android:background="@drawable/back_button"
        android:layout_marginBottom="200dp"
        android:layout_marginLeft="100dp"
        android:textSize="20dp"/>

    <Button
        android:id="@+id/button_6"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:text="6"
        android:textColor="#000000"
        android:layout_alignParentBottom="true"
        android:background="@drawable/back_button"
        android:layout_marginBottom="200dp"
        android:layout_marginLeft="190dp"
        android:textSize="20dp"/>

    <Button
        android:id="@+id/button_7"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:text="7"
        android:textColor="#000"
        android:layout_alignParentBottom="true"
        android:background="@drawable/back_button"
        android:layout_marginBottom="110dp"
        android:layout_marginLeft="10dp"
        android:textSize="20dp"/>

    <Button
        android:id="@+id/button_8"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:text="8"
        android:textColor="#000"
        android:background="@drawable/back_button"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="110dp"
        android:layout_marginLeft="100dp"
        android:textSize="20dp"/>

    <Button
        android:id="@+id/button_9"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:text="9"
        android:textColor="#000"
        android:background="@drawable/back_button"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="110dp"
        android:layout_marginLeft="190dp"
        android:textSize="20dp"/>

    <Button
        android:id="@+id/button_0"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:text="0"
        android:textColor="#000"
        android:background="@drawable/back_button"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="20dp"
        android:layout_marginLeft="100dp"
        android:textSize="20dp"/>

    <Button
        android:id="@+id/button_left"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:text="("
        android:textColor="#000"
        android:background="@drawable/back_button"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="20dp"
        android:layout_marginLeft="10dp"
        android:textSize="20dp"/>

    <Button
        android:id="@+id/button_right"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:text=")"
        android:textColor="#000"
        android:background="@drawable/back_button"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="20dp"
        android:layout_marginLeft="190dp"
        android:textSize="20dp"/>

    <Button
        android:id="@+id/button_point"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:layout_alignParentRight="true"
        android:layout_marginRight="10dp"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="110dp"
        android:background="@drawable/back_button"
        android:text="·"
        android:textSize="20dp"/>


    <Button
        android:id="@+id/button_equal"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_marginRight="10dp"
        android:layout_marginBottom="20dp"
        android:background="@drawable/back_button2"
        android:text="="
        android:textColor="#fff"
        android:textSize="20dp"/>

    <Button
        android:id="@+id/button_add"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:text="+"
        android:layout_alignParentBottom="true"
        android:textColor="#0066FF"
        android:background="@drawable/back_button"
        android:layout_marginBottom="380dp"
        android:layout_marginLeft="100dp"
        android:textSize="20dp"/>

    <Button
        android:id="@+id/button_subtraction"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:text="-"
        android:layout_alignParentBottom="true"
        android:textColor="#0066FF"
        android:background="@drawable/back_button"
        android:layout_marginBottom="380dp"
        android:layout_marginLeft="190dp"/>

    <Button
        android:id="@+id/button_multiplication"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:text="X"
        android:textColor="#0066FF"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:background="@drawable/back_button"
        android:layout_marginBottom="290dp"
        android:layout_marginRight="10dp"
        android:textSize="20dp"/>

    <Button
        android:id="@+id/button_division"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:text="/"
        android:textColor="#0066FF"
        android:background="@drawable/back_button"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_marginBottom="200dp"
        android:layout_marginRight="10dp"
        android:textSize="20dp"/>

    <Button
        android:id="@+id/button_clear"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:layout_alignParentBottom="true"
        android:text="C"
        android:textColor="#0066FF"
        android:background="@drawable/back_button"
        android:layout_marginBottom="380dp"
        android:layout_marginLeft="10dp"
        android:textSize="20dp"/>

    <Button
        android:id="@+id/button_delete"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:text="Del"
        android:textColor="#0066FF"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:background="@drawable/back_button"
        android:layout_marginBottom="380dp"
        android:layout_marginRight="10dp"
        android:textAllCaps="false"
        android:textSize="20dp"/>


</RelativeLayout>

上面是我的布局代码,我使用了RelativeLayout这种布局方式,这样方便Button的放置,这样就可以Button在屏幕上更好找到自己的位置。页面设置也没什么好说的,直接看下效果吧!
请添加图片描述
上面这是真机的演示效果,由于手机屏幕的大小不同,可能效果也不同,以上布局是我根据我自己手机所制作的,可能因手机大小会有差异。
布局这块非常的简单,非常容易做出来。下来就是点击事件的加入了。

Button的点击事件

注册点击事件也很简单;在前期的处理上,它是非常简单的,但如果你前期处理时让它过于简单了,就会让后面优化变得非常的让人头疼。我是用一个StringBuilder将所输入的数字所记录下来,这样就比直接用字符串节省许多的内存,并且在删除时也会特别的方便,不会让字符串反复的创建,节省了大量的内存。我是在这块处理了很多的东西,好多不合法的内容就不会被输入进去,所以在后面的计算方面就会变得非常的方便,但这样做也有坏处,就是做了大量的判断。代码毕竟不会像我们人一样会思考,所以只能用这样的方法将一些不合法的输入就杜绝了。

@Override
    public void onClick(View v) {

        switch (v.getId()) {
            case R.id.button_1:

                if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
                    stringBuilder.delete(0, stringBuilder.length());
                }
                if (stringBuilder.length() != 0 && stringBuilder.charAt(stringBuilder.length()-1) == ')') {
                    stringBuilder.append("*");
                }
                if (stringBuilder.length() != 0 && zero == false
                        && stringBuilder.charAt(stringBuilder.length()-1) == '0') {
                    stringBuilder.deleteCharAt(stringBuilder.length()-1);
                }
                zero = true;
                stringBuilder.append(1);
                editText.setText(stringBuilder.toString());
                break;
            case R.id.button_2:
                if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
                    stringBuilder.delete(0, stringBuilder.length());
                }
                if (stringBuilder.length() != 0 && stringBuilder.charAt(stringBuilder.length()-1) == ')') {
                    stringBuilder.append("*");
                }
                if (stringBuilder.length() != 0 && zero == false
                        && stringBuilder.charAt(stringBuilder.length()-1) == '0') {
                    stringBuilder.deleteCharAt(stringBuilder.length()-1);
                }
                zero = true;
                stringBuilder.append(2);
                editText.setText(stringBuilder.toString());
                break;
            case R.id.button_3:
                if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
                    stringBuilder.delete(0, stringBuilder.length());
                }
                if (stringBuilder.length() != 0 && stringBuilder.charAt(stringBuilder.length()-1) == ')') {
                    stringBuilder.append("*");
                }
                if (stringBuilder.length() != 0 && zero == false
                        && stringBuilder.charAt(stringBuilder.length()-1) == '0') {
                    stringBuilder.deleteCharAt(stringBuilder.length()-1);
                }
                zero = true;
                stringBuilder.append(3);
                editText.setText(stringBuilder.toString());
                break;
            case R.id.button_4:
                if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
                    stringBuilder.delete(0, stringBuilder.length());
                }
                if (stringBuilder.length() != 0 && stringBuilder.charAt(stringBuilder.length()-1) == ')') {
                    stringBuilder.append("*");
                }
                if (stringBuilder.length() != 0 && zero == false
                        && stringBuilder.charAt(stringBuilder.length()-1) == '0') {
                    stringBuilder.deleteCharAt(stringBuilder.length()-1);
                }
                zero = true;
                stringBuilder.append(4);
                editText.setText(stringBuilder.toString());
                break;
            case R.id.button_5:
                if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
                    stringBuilder.delete(0, stringBuilder.length());
                }
                if (stringBuilder.length() != 0 && stringBuilder.charAt(stringBuilder.length()-1) == ')') {
                    stringBuilder.append("*");
                }
                if (stringBuilder.length() != 0 && zero == false
                        && stringBuilder.charAt(stringBuilder.length()-1) == '0') {
                    stringBuilder.deleteCharAt(stringBuilder.length()-1);
                }
                zero = true;
                stringBuilder.append(5);
                editText.setText(stringBuilder.toString());
                break;
            case R.id.button_6:
                if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
                    stringBuilder.delete(0, stringBuilder.length());
                }
                if (stringBuilder.length() != 0 && stringBuilder.charAt(stringBuilder.length()-1) == ')') {
                    stringBuilder.append("*");
                }
                if (stringBuilder.length() != 0 && zero == false
                        && stringBuilder.charAt(stringBuilder.length()-1) == '0') {
                    stringBuilder.deleteCharAt(stringBuilder.length()-1);
                }
                zero = true;
                stringBuilder.append(6);
                editText.setText(stringBuilder.toString());
                break;
            case R.id.button_7:
                if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
                    stringBuilder.delete(0, stringBuilder.length());
                }
                if (stringBuilder.length() != 0 && stringBuilder.charAt(stringBuilder.length()-1) == ')') {
                    stringBuilder.append("*");
                }
                if (stringBuilder.length() != 0 && zero == false
                        && stringBuilder.charAt(stringBuilder.length()-1) == '0') {
                    stringBuilder.deleteCharAt(stringBuilder.length()-1);
                }
                zero = true;
                stringBuilder.append(7);
                editText.setText(stringBuilder.toString());
                break;
            case R.id.button_8:
                if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
                    stringBuilder.delete(0, stringBuilder.length());
                }
                if (stringBuilder.length() != 0 && stringBuilder.charAt(stringBuilder.length()-1) == ')') {
                    stringBuilder.append("*");
                }
                if (stringBuilder.length() != 0 && zero == false
                        && stringBuilder.charAt(stringBuilder.length()-1) == '0') {
                    stringBuilder.deleteCharAt(stringBuilder.length()-1);
                }
                zero = true;
                stringBuilder.append(8);
                editText.setText(stringBuilder.toString());
                break;
            case R.id.button_9:
                if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
                    stringBuilder.delete(0, stringBuilder.length());
                }
                if (stringBuilder.length() != 0 && stringBuilder.charAt(stringBuilder.length()-1) == ')') {
                    stringBuilder.append("*");
                }
                if (stringBuilder.length() != 0 && zero == false
                        && stringBuilder.charAt(stringBuilder.length()-1) == '0') {
                    stringBuilder.deleteCharAt(stringBuilder.length()-1);
                }
                zero = true;
                stringBuilder.append(9);
                editText.setText(stringBuilder.toString());
                break;
            case R.id.button_0:
                if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
                    stringBuilder.delete(0, stringBuilder.length());
                }
                if (stringBuilder.length() != 0 && stringBuilder.charAt(stringBuilder.length()-1) == ')') {
                    stringBuilder.append("*");
                }
                if (zero) {
                    stringBuilder.append(0);
                    editText.setText(stringBuilder.toString());
                } else {
                    if (stringBuilder.length() != 0 &&
                            stringBuilder.charAt(stringBuilder.length()-1) == '0') {
                        editText.setText(stringBuilder.toString());
                    } else {
                        stringBuilder.append(0);
                        editText.setText(stringBuilder.toString());
                    }
                }
                break;
            case R.id.button_equal:
                try {
                    if (stringBuilder.length() == 0) {
                        editText.setText(stringBuilder.toString());
                        point = 0;
                        flag1 = 0;
                        break;
                    } else if (stringBuilder.charAt(0) == 'E') {
                        stringBuilder.delete(0, stringBuilder.length());
                        editText.setText(stringBuilder.toString());
                        point = 0;
                        flag1 = 0;
                        break;
                    }
                    String result = countResult(change2(change1()));
                    stringBuilder.delete(0, stringBuilder.length());
                    stringBuilder.append(result);
                    flag1 = 0;
                    /*for (int i = 0; i < stringBuilder.length(); i++) {
                        if (stringBuilder.charAt(i) == '.') {
                            point = 1;
                            break;
                        } else {
                            point = 0;
                        }
                    }*/
                    if (result.matches("^[-\\+]?[\\d+]$")) {
                        point = 0;
                    } else {
                        point = 1;
                    }
                    editText.setText(stringBuilder.toString());
                    if (stringBuilder.toString().equals("0")) {
                        zero = false;
                    } else {
                        zero = true;
                    }
                } catch (Exception e) {
                    stringBuilder.delete(0, stringBuilder.length());
                    stringBuilder.append("Error");
                    editText.setText("Error");
                    point = 0;
                    flag1 = 0;
                }
                break;
            case R.id.button_delete:
                if (stringBuilder.length() == 2 && stringBuilder.charAt(0) == '-') {
                    stringBuilder.delete(0, stringBuilder.length());
                    editText.setText(stringBuilder.toString());
                    break;
                }
                if (stringBuilder.length() > 2
                        && stringBuilder.charAt(stringBuilder.length()-2) == '-'
                        && (stringBuilder.charAt(stringBuilder.length()-3) == '*' ||
                        stringBuilder.charAt(stringBuilder.length()-3) == '/' ||
                        stringBuilder.charAt(stringBuilder.length()-3) == '(')) {
                    stringBuilder.deleteCharAt(stringBuilder.length()-1);
                    stringBuilder.deleteCharAt(stringBuilder.length()-1);
                    editText.setText(stringBuilder.toString());
                    break;
                }
                if (stringBuilder.length() != 0) {
                    if (stringBuilder.charAt(0) == 'E') {
                        stringBuilder.delete(0, stringBuilder.length());
                        editText.setText(stringBuilder.toString());
                        break;
                    }
                    if (stringBuilder.charAt(stringBuilder.length()-1) == ')') {
                        flag1++;
                    } else if (stringBuilder.charAt(stringBuilder.length() - 1) == '.') {
                        point = 0;
                    } if (stringBuilder.charAt(stringBuilder.length()-1) == '(') {
                        flag1--;
                    }
                    stringBuilder.deleteCharAt(stringBuilder.length()-1);
                    editText.setText(stringBuilder.toString());

                } else {
                    zero = false;
                }
                break;
            case R.id.button_clear:
                stringBuilder.delete(0, stringBuilder.length());
                editText.setText(stringBuilder.toString());
                flag1 = 0;
                point = 0;
                zero = false;
                break;
            case R.id.button_add:
                if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
                    stringBuilder.delete(0, stringBuilder.length());
                    stringBuilder.append("+");
                    editText.setText(stringBuilder.toString());
                    point = 0;
                    zero = false;
                    break;
                }
                String str3 = stringBuilder.toString();
                if (str3.length() > 1 && "-".equals(str3.substring(str3.length()-1))
                        && !"*".equals(str3.substring(str3.length()-2,str3.length()-1))
                        && !"/".equals(str3.substring(str3.length()-2,str3.length()-1))
                        && !"(".equals(str3.substring(str3.length()-2,str3.length()-1))) {
                    stringBuilder.deleteCharAt(stringBuilder.length() - 1);
                    stringBuilder.append("+");
                    editText.setText(stringBuilder.toString());
                    break;
                }
                if (stringBuilder.length() != 0 &&
                        !"+".equals(str3.substring(str3.length()-1)) &&
                        !"*".equals(str3.substring(str3.length()-1)) &&
                        !"/".equals(str3.substring(str3.length()-1)) &&
                        !"-".equals(str3.substring(str3.length()-1)) ) {
                    if (stringBuilder.charAt(stringBuilder.length()-1) == '.') {
                        stringBuilder.append(0);
                    }
                    stringBuilder.append("+");
                    editText.setText(stringBuilder.toString());
                    point = 0;
                    zero = false;
                }

                break;
            case R.id.button_subtraction:
                if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
                    stringBuilder.delete(0, stringBuilder.length());
                    stringBuilder.append("-");
                    editText.setText(stringBuilder.toString());
                    point = 0;
                    zero = false;
                    break;
                }
                if (stringBuilder.length() == 0) {
                    stringBuilder.append("-");
                    editText.setText(stringBuilder.toString());
                    point = 0;
                    break;
                }
                String str4 = stringBuilder.toString();
                if (stringBuilder.length() != 0 && "+".equals(str4.substring(str4.length()-1))) {
                    stringBuilder.deleteCharAt(stringBuilder.length() - 1);
                    stringBuilder.append("-");
                    editText.setText(stringBuilder.toString());

                    break;
                }
                if (!"-".equals(str4.substring(str4.length()-1) ) &&
                        !"+".equals(str4.substring(str4.length()-1) )) {
                    if (stringBuilder.charAt(stringBuilder.length()-1) == '.') {
                        stringBuilder.append(0);
                    }
                    stringBuilder.append("-");
                    editText.setText(stringBuilder.toString());
                    point = 0;
                }
                break;
            case R.id.button_multiplication:
                if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
                    stringBuilder.delete(0, stringBuilder.length());
                    editText.setText(stringBuilder.toString());
                    point = 0;
                    zero = false;
                    break;
                }

                if (stringBuilder.length() != 0) {
                    String str5 = stringBuilder.toString();
                    if (!"+".equals(str5.substring(str5.length()-1) ) &&
                            !"-".equals(str5.substring(str5.length()-1) ) &&
                            !"*".equals(str5.substring(str5.length()-1) ) &&
                            !"/".equals(str5.substring(str5.length()-1) )) {
                        if (stringBuilder.charAt(stringBuilder.length()-1) == '.') {
                            stringBuilder.append(0);
                        }
                        stringBuilder.append("*");
                        editText.setText(stringBuilder.toString());
                        point = 0;
                        zero = false;
                    }
                }
                break;
            case R.id.button_division:
                if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
                    stringBuilder.delete(0, stringBuilder.length());
                    editText.setText(stringBuilder.toString());
                    point = 0;
                    zero = false;
                    break;
                }
                if (stringBuilder.length() != 0) {
                    String str6 = stringBuilder.toString();
                    if (!"+".equals(str6.substring(str6.length()-1) ) &&
                            !"-".equals(str6.substring(str6.length()-1) ) &&
                            !"*".equals(str6.substring(str6.length()-1) ) &&
                            !"/".equals(str6.substring(str6.length()-1) )) {
                        if (stringBuilder.charAt(stringBuilder.length()-1) == '.') {
                            stringBuilder.append(0);
                        }
                        stringBuilder.append("/");
                        editText.setText(stringBuilder.toString());
                        point = 0;
                        zero = false;
                    }
                }
                break;
            case R.id.button_left:
                if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
                    stringBuilder.delete(0, stringBuilder.length());
                    stringBuilder.append("(");
                    editText.setText(stringBuilder.toString());
                    flag1++;
                    point = 0;
                    zero = false;
                    break;
                }
                if (stringBuilder.length() == 0) {
                    stringBuilder.append("(");
                    editText.setText(stringBuilder.toString());
                    flag1++;
                    point = 0;
                    break;
                } else {
                    String str7 = stringBuilder.toString();
                    if (".".equals(str7.substring(str7.length()-1))) {
                        stringBuilder.append(0);
                        stringBuilder.append("*");
                        stringBuilder.append("(");
                        editText.setText(stringBuilder.toString());
                        point = 0;
                        zero = false;
                        flag1++;
                    } else if (stringBuilder.charAt(stringBuilder.length()-1) >= '0'
                            && stringBuilder.charAt(stringBuilder.length()-1) <= '9') {
                        stringBuilder.append("*");
                        stringBuilder.append("(");
                        editText.setText(stringBuilder.toString());
                        point = 0;
                        flag1++;
                        zero = false;
                    } else if (stringBuilder.charAt(stringBuilder.length()-1) == ')') {
                        stringBuilder.append("*");
                        stringBuilder.append("(");
                        editText.setText(stringBuilder.toString());
                        flag1++;
                        point = 0;
                        zero = false;
                    } else {
                            stringBuilder.append("(");
                            editText.setText(stringBuilder.toString());
                            point = 0;
                            flag1++;
                            zero = false;
                        }
                    }
                    break;
            case R.id.button_right:
                String str1 = stringBuilder.toString();
                if (flag1 > 0) {
                    if (!".".equals(str1.substring(str1.length()-1)) &&
                    !"(".equals(str1.substring(str1.length()-1)) &&
                            !"+".equals(str1.substring(str1.length()-1) ) &&
                            !"-".equals(str1.substring(str1.length()-1) ) &&
                            !"*".equals(str1.substring(str1.length()-1) ) &&
                            !"/".equals(str1.substring(str1.length()-1) )) {
                        stringBuilder.append(")");
                        point = 0;
                        editText.setText(stringBuilder.toString());
                        flag1--;
                        zero = false;
                    } else if (stringBuilder.charAt(stringBuilder.length()-1) == '.') {
                        stringBuilder.append(0);
                        stringBuilder.append(")");
                        point = 0;
                        editText.setText(stringBuilder.toString());
                        flag1--;
                        zero = false;
                    }
                }
                break;
            case R.id.button_point:
                if (stringBuilder.length() != 0 && stringBuilder.charAt(0) == 'E') {
                    stringBuilder.delete(0, stringBuilder.length());
                    stringBuilder.append(0);
                    stringBuilder.append(".");
                    editText.setText(stringBuilder.toString());
                    point = 1;
                    zero = true;
                    break;
                }
                String str2 = stringBuilder.toString();
                if (stringBuilder.length() != 0 &&
                        !"(".equals(str2.substring(str2.length()-1)) &&
                        !")".equals(str2.substring(str2.length()-1)) &&
                        !"+".equals(str2.substring(str2.length()-1)) &&
                        !"-".equals(str2.substring(str2.length()-1)) &&
                        !"*".equals(str2.substring(str2.length()-1)) &&
                        !"/".equals(str2.substring(str2.length()-1)) ) {
                    if (point == 0) {
                        stringBuilder.append(".");
                        editText.setText(stringBuilder.toString());
                        point = 1;
                    }
                    zero = true;
                } else {
                    if (point == 0) {
                        stringBuilder.append(0);
                        stringBuilder.append(".");
                        editText.setText(stringBuilder.toString());
                        point = 1;
                        zero = true;
                    }

                }
                break;
            default:
                break;
        }
    }

上面代码看着非常的多,做了许多的判断,但这样就保证了我的后面算法就会变得非常的好进行运算,因为没有了大多的非法输入,也会是许多错误避免了,运算效率就提高了。这里面有许多的判断,因为那些判断是属于优化程序的,所以后面再讲他们的部分作用吧。

计算器的核心部分

计算器的核心部分就是计算出结果,前面做的全部都是准备工作,现在才开始计算其最为重要的部分。首先,我们要将其输入的StringBuilder转换为我们要进行计算的形式,所以就出现了我的change1()方法。我的这个方法是干什么的,就是将我的StringBuilder转换为中缀表达式,为接下来的转后缀表达式做准备。下面是我的change1()方法。

private ArrayList<String> change1() {

        ArrayList<String> list = new ArrayList<>();

        while (flag1 > 0) {
            stringBuilder.append(")");
            --flag1;
        }
        if (stringBuilder.charAt(stringBuilder.length()-1) == '.') {
            stringBuilder.append(0);
        }

        String str = stringBuilder.toString();
        String s = "";

        for (int i = 0; i < str.length(); ) {
            if (str.charAt(i) == '(') {
                list.add(str.substring(i, i+1));
                i++;
                continue;
            }
            if (str.charAt(i) == '+') {
                list.add(str.substring(i, i+1));
                i++;
                continue;
            }
            if (str.charAt(i) == '-') {
                if (!(i != 0 && (str.charAt(i-1) == '*' || str.charAt(i-1) == '/'))) {
                    list.add(str.substring(i, i+1));
                    i++;
                    continue;
                }

            }

            if (str.charAt(i) == '*') {
                list.add(str.substring(i, i+1));
                i++;
                continue;
            }
            if (str.charAt(i) == '/') {
                list.add(str.substring(i, i+1));
                i++;
                continue;
            }
            if (str.charAt(i) == ')') {
                list.add(str.substring(i, i+1));
                i++;
                continue;
            }
            while (i < str.length() && ((str.charAt(i) <= '9' && str.charAt(i) >= '0') ||
                    str.charAt(i) == '.' ||
                    (str.charAt(i) == '-' && (str.charAt(i-1) == '*' || str.charAt(i-1) == '/')))) {
                s = s + str.charAt(i);
                i++;

            }
            list.add(s);
            s = "";
        }

        return list;
    }

在这个部分中,我也优化了当用户输入左括号时忘记输入右括号所带来的错误,我在这直接将右括号直接补上了,但是这样就表示你忘记输入的右括号就只能在最后了,我觉得开发者能做的只能是这些了,如果这样导致和使用者所想的结果不同,我觉得这不是bug,这应该是使用者的粗心,因为开发者能想到的只能是将括号加在最后面,开发者不能知道使用者是如何去想的。
接下来就是中缀表达式转后缀表达式了,我觉得这个是这个计算器中最难的一个部分了,先看代码。

private ArrayList<String> change2(ArrayList<String> list1) {
        ArrayList<String> list = new ArrayList<>();
        Stack<String> myStack = new Stack<>();

        String temp;
        for (int i = 0;i < list1.size();i++) {
            if (isNumber(list1.get(i))) {
                list.add(list1.get(i));
            } else if (list1.get(i).equals("(")) {
                myStack.push(list1.get(i));
            } else if (list1.get(i).equals("+") || list1.get(i).equals("-")) {
                if (list1.get(i).equals("-") && (i == 0 || list1.get(i-1).equals("("))) {
                    list.add("0");
                }
                while (!myStack.isEmpty()) {
                    temp = myStack.pop();
                    if ("(".equals(temp)) {
                        myStack.push(temp);
                        break;
                    }
                    list.add(temp);
                }
                myStack.push(list1.get(i));
            } else if (list1.get(i).equals("*") || list1.get(i).equals("/")) {
                while (!myStack.isEmpty()) {
                    temp = myStack.pop();
                    if ("(".equals(temp) || "+".equals(temp) || "-".equals(temp)) {
                        myStack.push(temp);
                        break;
                    }
                    list.add(temp);
                }
                myStack.push(list1.get(i));
            } else if (list1.get(i).equals(")")) {
                while (!"(".equals(myStack.peek())) {
                    list.add(myStack.pop());
                }
                myStack.pop();
            }
        }

        while (!myStack.isEmpty()) {
            list.add(myStack.pop());
        }
        return list;
    }

这是中缀表达转后缀表达式,只要输入的式子正确,我觉得应该都能转换出来,这其实就是一个进栈出栈的过程,如果不会,建议继续学习一下数据结构。
最后就是后缀表达式的求值问题,这也是数据结构那的知识,我就不细讲了。我用的是BigDecimal来进行计算的,这样就能够保证数字不管是大数还是小数都能计算。最后还要处理小数点后面的0的问题。

private String countResult(ArrayList<String> list) {
        Stack<BigDecimal> myStack = new Stack<>();
        BigDecimal bigDecimal_1, bigDecimal_2;
        for (String string : list) {
            if (isNumber(string)) {
                myStack.push(new BigDecimal(string));
            } else {
                bigDecimal_1 = myStack.pop();
                bigDecimal_2 = myStack.pop();
                switch (string) {
                    case "+" :
                        myStack.push(bigDecimal_1.add(bigDecimal_2));
                        break;
                    case "-" :
                        myStack.push(bigDecimal_2.subtract(bigDecimal_1));
                        break;
                    case "*" :
                        myStack.push(bigDecimal_1.multiply(bigDecimal_2));
                        break;
                    case "/" :
                        myStack.push(bigDecimal_2.divide(bigDecimal_1,5,BigDecimal.ROUND_HALF_UP));
                        break;
                }
            }
        }

        return deleteZero(myStack.peek().toString());

    }

    private String deleteZero(String string) {
        if(string.indexOf(".") > 0){
            string = string.replaceAll("0+?$", "");
            string = string.replaceAll("[.]$", "");
        }
        return string;
    }

优化

上面的计算器已经可以进行计算了,但是没讲如何进行优化的,接下来我简单讲一下我是如何进行优化的。在直接输入一个小数点时,就可以在前面补上0,因为你已经输入了小数点,单独输入小数点是没有意义的,所以我就直接加上了0.在输入小数点后没有输入任何数字时,输入了运算符,就会在小数点后面添加一个0,这样就不会出现运算错误了。
然后就是在输入括号时,默认是输入了一个括号,这也符合我们的使用习惯。
还优化了小数点,不能输入多个小数点,不能连续输入多个0.
还优化了一些细节。可能没写到。
这是我学习Android写的第一个app,以后还会有很多的项目去做,希望自己能够写的越来越好!
这是Github源码地址:
GitHub源码地址

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值