天天看点

计算器——第一个Android小项目Android计算器

Android计算器

目录

这是我第一个Android小项目,相信这也是大多数人的第一个小项目。

这个项目非常的简单,只有一个Activity。

首先是布局文件,这里我用的是线性布局。

计算器的布局

这个布局文件中的按钮(Button)比较多。

首先是一个TextView,然后是一堆按钮。

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

    <LinearLayout
        android:id="@+id/text_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2"
        >

        <TextView
            android:id="@+id/text_edit"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#ffffff"
            android:textColor="#e51c23"
            android:gravity="bottom|right"
            android:textSize="30sp" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/button_1line"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal">

        <Button
            android:id="@+id/button_left"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="("
            android:textSize="30sp" />

        <Button
            android:id="@+id/button_right"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:layout_marginLeft="-8dp"
            android:text=")"
            android:textSize="30sp" />

        <Button
            android:id="@+id/button_clear"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_marginLeft="-8dp"
            android:layout_weight="1"
            android:text="C"
            android:textSize="30sp" />

        <Button
            android:id="@+id/button_back"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_marginLeft="-8dp"
            android:layout_weight="1"
            android:text="<Del"
            android:textAllCaps="false"
            android:textSize="25sp" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/button_2line"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal" >
        <Button
            android:id="@+id/button_7"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="7"
            android:textSize="30sp"
            />

        <Button
            android:id="@+id/button_8"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:layout_marginLeft="-8dp"
            android:text="8"
            android:textSize="30sp"
            />
        <Button
            android:id="@+id/button_9"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:layout_marginLeft="-8dp"
            android:text="9"
            android:textSize="30sp"
            />

        <Button
            android:id="@+id/button_add"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:layout_marginLeft="-8dp"
            android:text="+"
            android:textSize="40sp" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/button_3line"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/button_4"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="4"
            android:textSize="30sp"
            />

        <Button
            android:id="@+id/button_5"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="5"
            android:layout_marginLeft="-8dp"
            android:textSize="30sp"
            />
        <Button
            android:id="@+id/button_6"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:layout_marginLeft="-8dp"
            android:text="6"
            android:textSize="30sp"
            />

        <Button
            android:id="@+id/button_minus"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:layout_marginLeft="-8dp"
            android:text="-"
            android:textSize="50sp" />
    </LinearLayout>
    <LinearLayout
        android:id="@+id/button_4line"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/button_1"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="1"
            android:textSize="30sp"
            />

        <Button
            android:id="@+id/button_2"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:layout_marginLeft="-8dp"
            android:text="2"
            android:textSize="30sp"
            />
        <Button
            android:id="@+id/button_3"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:layout_marginLeft="-8dp"
            android:text="3"
            android:textSize="30sp"
            />

        <Button
            android:id="@+id/button_mul"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:layout_marginLeft="-8dp"
            android:text="×"
            android:textSize="35sp" />
    </LinearLayout>
    <LinearLayout
        android:id="@+id/button_5line"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/button_point"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="."
            android:textSize="40sp" />

        <Button
            android:id="@+id/button_0"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_marginLeft="-8dp"
            android:layout_weight="1"
            android:text="0"
            android:textSize="30sp" />


        <Button
            android:id="@+id/button_div"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="÷"
            android:layout_marginLeft="-8dp"
            android:textSize="40sp" />

        <Button
            android:id="@+id/button_equals"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:layout_marginLeft="-5dp"
            android:text="="
            android:background="#3388FF"
            android:textSize="50sp"
            />
    </LinearLayout>
</LinearLayout>
           

接下来就是ManActivity中的代码了,当然其中主要就是一个按钮的监听,也没有什么难度。

MainActivity中的代码

package com.example.calculatortest;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;


public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    StringBuffer sb = new StringBuffer();
    private TextView text = null;   // 用于显示输入和输出
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.simple_1);
        getSupportActionBar().hide();
        text = (TextView) findViewById(R.id.text_edit);
        // 数字按钮
        Button button0 = (Button)findViewById(R.id.button_0);
        Button button1 = (Button)findViewById(R.id.button_1);
        Button button2 = (Button)findViewById(R.id.button_2);
        Button button3 = (Button)findViewById(R.id.button_3);
        Button button4 = (Button)findViewById(R.id.button_4);
        Button button5 = (Button)findViewById(R.id.button_5);
        Button button6 = (Button)findViewById(R.id.button_6);
        Button button7 = (Button)findViewById(R.id.button_7);
        Button button8 = (Button)findViewById(R.id.button_8);
        Button button9 = (Button)findViewById(R.id.button_9);

        // 功能按钮
        // 四则运算
        Button button_div = (Button)findViewById(R.id.button_div);
        Button button_mul = (Button)findViewById(R.id.button_mul);
        Button button_add = (Button)findViewById(R.id.button_add);
        Button button_minus = (Button) findViewById(R.id.button_minus);

        Button button_back  = (Button)findViewById(R.id.button_back);
        Button button_clear = (Button) findViewById(R.id.button_clear);

        Button button_point = (Button) findViewById(R.id.button_point);
        Button button_equals = (Button) findViewById(R.id.button_equals);

        // 左右括号
        Button button_left = (Button) findViewById(R.id.button_left);
        Button button_right = (Button) findViewById(R.id.button_right);


        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);

        button_add.setOnClickListener(this);
        button_minus.setOnClickListener(this);
        button_mul.setOnClickListener(this);
        button_div.setOnClickListener(this);

        button_back.setOnClickListener(this);
        button_clear.setOnClickListener(this);

        button_point.setOnClickListener(this);
        button_equals.setOnClickListener(this);

        button_left.setOnClickListener(this);
        button_right.setOnClickListener(this);
    }

    private String sign = "+-*/";
    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.button_1:
                sb.append("1");
                text.setText(sb);
                break;
            case R.id.button_2:
                sb.append("2");
                text.setText(sb);
                break;
            case R.id.button_3:
                sb.append("3");
                text.setText(sb);
                break;
            case R.id.button_4:
                sb.append("4");
                text.setText(sb);
                break;
            case R.id.button_5:
                sb.append("5");
                text.setText(sb);
                break;
            case R.id.button_6:
                sb.append("6");
                text.setText(sb);
                break;
            case R.id.button_7:
                sb.append("7");
                text.setText(sb);
                break;
            case R.id.button_8:
                sb.append("8");
                text.setText(sb.toString());
                break;
            case R.id.button_9:
                sb.append("9");
                text.setText(sb);
                break;
            case R.id.button_0:
                sb.append("0");
                text.setText(sb);
                break;
            case R.id.button_back:
                if(sb.length() > ) {
                    sb.deleteCharAt(sb.length() - );
                    text.setText(sb);
                }
                break;
            case R.id.button_clear:
                sb.setLength();
                text.setText(sb);
                break;
            case R.id.button_add:
                if(sb.length() >  && sign.indexOf(sb.charAt(sb.length() - )) == -) {
                    sb.append("+");
                }
                text.setText(sb);
                break;
            case R.id.button_minus:
                if(sb.length() ==  || sb.length() >  && sign.indexOf(sb.charAt(sb.length() - )) == -) {
                    sb.append("-");
                }
                text.setText(sb);
                break;
            case R.id.button_mul:
                if(sb.length() >  && sign.indexOf(sb.charAt(sb.length() - )) == -) {
                    sb.append("×");
                }
                text.setText(sb);
                break;
            case R.id.button_div:
                if(sb.length() >  && sign.indexOf(sb.charAt(sb.length() - )) == -) {
                    sb.append("÷");
                }
                text.setText(sb);
                break;
            case R.id.button_point:
                if(sb.length() ==  ||!Character.isDigit(sb.charAt(sb.length() - ))) {
                    sb.append("0.");
                }
                else {
                    sb.append(".");
                }
                text.setText(sb);
                break;
            case R.id.button_left:
                sb.append("(");
                text.setText(sb);
                break;
            case R.id.button_right:
                if (sb.indexOf("(") != -) {
                    sb.append(")");
                }
                text.setText(sb);
                break;
            case R.id.button_equals:
                String s = sb.toString().replace("×", "*").replace("÷", "/");
                try {
                    s = Calculator.toSuffix(s);
                } catch (Exception ex) {
                    s  = "出错";
                }
                text.setText(sb + "\n"+"=" + s);

                if (s != "出错") {
                    sb = new StringBuffer(s);
                }else {
                    sb.delete(, sb.length());
                }
                break;
        }
    }
}
           

当然还有一个Calculator类,这个就是计算的核心代码了,这个类中用的是中缀转后缀来计算的,当然如果看不懂,可以看我的这个博客:

package com.example.calculatortest;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.ArrayDeque;



public class Calculator {

    public static String toSuffix(String input) {
        int len = input.length();
        char c, tempChar;
        ArrayDeque<Character> s1 = new ArrayDeque<Character>();
        ArrayDeque<BigDecimal> s2 = new ArrayDeque<>();
        int lastIndex = -;
        for (int i = ; i < len; ++i) {
            c = input.charAt(i);
            if (Character.isDigit(c) || c == '.') {
                lastIndex = readDouble(input, i);
                if (lastIndex == -)
                    return "出错";

                BigDecimal number = new BigDecimal(input.substring(i, lastIndex));
                s2.push(number);
                i = lastIndex - ;

            }else if (c == '-' && i == ) {
                lastIndex = readDouble(input, i + );
                if (lastIndex == -)
                    return "出错";
                BigDecimal number = new BigDecimal(input.substring(i, lastIndex));
                s2.push(number);
                i = lastIndex - ;

            }else if (i >  && c == '-' &&
                    (input.charAt(i-) == '('
                            || isOperator(input.charAt(i-)))) {
                lastIndex = readDouble(input, i + );
                if (lastIndex == -)
                    return "出错";
                BigDecimal number = new BigDecimal(input.substring(i, lastIndex));
                s2.push(number);
                i = lastIndex - ;

            }
            else if (isOperator(c)) {
                while (!s1.isEmpty() && s1.peek() != '('
                        && priorityCompare(c, s1.peek()) <= ) {
//                    double num1 = s2.pop();
//                    double num2 = s2.pop();
                    BigDecimal num1 = s2.pop();
                    BigDecimal num2 = s2.pop();

                    s2.push(calc(num2, num1, s1.pop()));
                }
                s1.push(c);
            } else if (c == '(') {
                s1.push(c);
            } else if (c == ')') {
                while ((tempChar = s1.pop()) != '(') {
//                    double num1 = s2.pop();
//                    double num2 = s2.pop();
                    BigDecimal num1 = s2.pop();
                    BigDecimal num2 = s2.pop();
                    s2.push(calc(num2, num1, tempChar));
                    if (s1.isEmpty()) {
                        return "出错";
                    }
                }
            } else if (c == ' ') {
                // ignore
            } else {
                return "出错";
            }
        }
        while (!s1.isEmpty()) {
            tempChar = s1.pop();
//            double num1 = s2.pop();
//            double num2 = s2.pop();
            BigDecimal num1 = s2.pop();
            BigDecimal num2 = s2.pop();
            s2.push(calc(num2, num1, tempChar));
        }
        BigDecimal result = s2.pop();
        if (!s2.isEmpty())
            return "出错";
        if (result.toString().length() < )
            return result.stripTrailingZeros().toPlainString();
        else
            return result.round(new MathContext(, RoundingMode.HALF_UP)).toEngineeringString();
    }

    /**
     * 获取是double值得最后一位索引
     */
    public static int readDouble(String str, int start)
            throws IllegalArgumentException{
        int len = str.length();
        int dotIndex = -;
        char ch;
        for (int i = start; i < len ; i++) {
            ch = str.charAt(i);
            if(ch == '.') {
                if(dotIndex != -)
                    return -;
                else if(i == len - )
                    return -;
                else
                    dotIndex = i;
            } else if(!Character.isDigit(ch)) {
                if (dotIndex == - || i - dotIndex > )
                    return i;
                else
                    throw new IllegalArgumentException("不是数字,不能作为数字的一部分");
            }
            else if(i == len - ) {
                return len;
            }
        }
        return -;
    }



    /**
     * 判断优先级
     */

    private static int priorityCompare (char op1, char op2) {
        if(op1 == '+' || op1 == '-')
            return (op2 == '*' || op2 == '/' ? - : );
        if (op1 == '*' || op1 == '/') {
            return (op2 == '+' || op2 == '-' ?  : );
        }
        return ;
    }


    /**
     * 这个函数能够判断是否是操作运算符
     */

    private static boolean isOperator (char ch) {
        return (ch == '+' || ch == '-' || ch == '*' || ch == '/');
    }

    /**
     * 计算两个数的结果
     * 并返回
     */
    private static BigDecimal calc (BigDecimal num1, BigDecimal num2, char op)
            throws IllegalArgumentException{
        switch (op) {
            case '+':
                return num1.add(num2);
            case '-':
                return num1.subtract(num2);
            case '*':
                return num1.multiply(num2);
            case '/':
                if (num2.equals())
                    throw new IllegalArgumentException("除数不能为0");
                return num1.divide(num2, , RoundingMode.HALF_UP);
            default:
                return new BigDecimal();
        }

    }
}