用Android Studio制作一个简易的计算器

用Android Studio制作一个简易的计算器

一,前言

虽然现在我们日常生活中很少用到计算器,但在一些数学题或者物理题目上还是非常有帮助的,所以我就想在Android Studio上做一个计算器

二,代码部分

1,显示部分(activity_main.xml)

grid layout的一些使用属性

android:id="@+id/gridlayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#F0F0F0"
    android:alignmentMode="alignBounds"
    android:rowCount="9"
    android:columnCount="4"
    android:orientation="horizontal"

    tools:context=".MainActivity"
    tools:ignore="GridLayout">
   

接着是计算器的各个按钮

 android:id="@+id/edit"
        android:layout_gravity="right|bottom"
        android:text="0"
        android:textSize="35dp"
        android:layout_columnSpan="4"
        android:layout_rowWeight="2"
        android:layout_columnWeight="1"
        android:background="@null"/>
    android:id="@+id/view"
        android:layout_gravity="right|bottom"
        android:text="0"
        android:textSize="55dp"
        android:layout_columnSpan="4"
        android:layout_rowWeight="2"
        android:layout_columnWeight="1"/>
    

然后我们开一下呈现出来的图是什么样子的(如下)
在这里插入图片描述
到这里我们就完成了1/3的工程,紧接着是让各个数字符号对应到各个按钮

2,连接部分(Main_Activity.java)

参考原文博客连接部分运用的是FindViewByMe(XML)这个插件,连接按钮变得十分方便。建立按钮后,如果每个都要单独设置监听事件会十分麻烦,所以有一个方法onClick方法,多个按钮一起监听。但是在使用此方法是必须连接View.OnClickListener接口。然后set后即可使用。

首先建立按钮(这只是单单的建议按钮,连接按钮的代码在底下)

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    private GridLayout gridlayout;
    private EditText edit;
    private TextView view;
    private Button add;
    private Button substact;
    private Button multiply;
    private Button divide;
    private Button seven;
    private Button eight;
    private Button nine;
    private Button left;
    private Button four;
    private Button five;
    private Button six;
    private Button right;
    private Button three;
    private Button two;
    private Button one;
    private Button Clean;
    private Button dot;
    private Button zero;
    private Button equal;
}

然后把每个按钮和对应的数字符号对应起来

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        gridlayout = (GridLayout) findViewById(R.id.gridlayout);
        edit = (EditText) findViewById(R.id.edit);
        view = (TextView) findViewById(R.id.view);
        add = (Button) findViewById(R.id.add);
        substact = (Button) findViewById(R.id.substact);
        multiply = (Button) findViewById(R.id.multiply);
        divide = (Button) findViewById(R.id.divide);
        seven = (Button) findViewById(R.id.seven);
        eight = (Button) findViewById(R.id.eight);
        nine = (Button) findViewById(R.id.nine);
        left = (Button) findViewById(R.id.left);
        four = (Button) findViewById(R.id.four);
        five = (Button) findViewById(R.id.five);
        six = (Button) findViewById(R.id.six);
        right = (Button) findViewById(R.id.right);
        three = (Button) findViewById(R.id.three);
        two = (Button) findViewById(R.id.two);
        one = (Button) findViewById(R.id.one);
        Clean = (Button) findViewById(R.id.Clean);
        dot = (Button) findViewById(R.id.dot);
        zero = (Button) findViewById(R.id.zero);
        equal = (Button) findViewById(R.id.equal);
        
        edit.setOnClickListener(this);
        view.setOnClickListener(this);
        add.setOnClickListener(this);
        multiply.setOnClickListener(this);
        divide.setOnClickListener(this);
        dot.setOnClickListener(this);
        one.setOnClickListener(this);
        two.setOnClickListener(this);
        three.setOnClickListener(this);
        four.setOnClickListener(this);
        five.setOnClickListener(this);
        six.setOnClickListener(this);
        seven.setOnClickListener(this);
        eight.setOnClickListener(this);
        nine.setOnClickListener(this);
        zero.setOnClickListener(this);
        right.setOnClickListener(this);
        Clean.setOnClickListener(this);
        left.setOnClickListener(this);
        equal.setOnClickListener(this);
        substact.setOnClickListener(this);
    }

记录上一个结果

   private String lastresult;

判断当前是否进行计算

 private boolean now;

点击按钮后会输出相对应的数字和符号(onClick)

    @Override
    public void onClick(View v) {
        String text = edit.getText().toString();//获取当前文本编译框内容
        String lasttext;
        boolean clean = false;
        Formulautil a = new Formulautil();
        if (text.equals("0"))
        {
            edit.setText("");
        }
        switch(v.getId())
        {
            case R.id.zero:
                edit.setText(edit.getText() + "0");
                Clean.setText("C");
                now = false;
                break;
            case R.id.one:
                edit.setText(edit.getText() + "1");
                Clean.setText("C");
                now = false;
                break;
            case R.id.two:
                edit.setText(edit.getText() + "2");
                Clean.setText("C");
                now = false;
                break;
            case R.id.three:
                edit.setText(edit.getText() + "3");
                Clean.setText("C");
                now = false;
                break;
            case R.id.four:
                edit.setText(edit.getText() + "4");
                Clean.setText("C");
                now = false;
                break;
            case R.id.five:
                edit.setText(edit.getText() + "5");
                Clean.setText("C");
                now = false;
                break;
            case R.id.six:
                edit.setText(edit.getText() + "6");
                Clean.setText("C");
                now = false;
                break;
            case R.id.seven:
                edit.setText(edit.getText() + "7");
                Clean.setText("C");
                now = false;
                break;
            case R.id.eight:
                edit.setText(edit.getText() + "8");
                Clean.setText("C");
                now = false;
                break;
            case R.id.nine:
                edit.setText(edit.getText() + "9");
                Clean.setText("C");
                now = false;
                break;
            case R.id.dot:
                edit.setText(edit.getText() + ".");
                Clean.setText("C");
                now = false;
                break;

            case R.id.right:
                edit.setText(edit.getText() + ")");
                Clean.setText("C");
                now = false;
                break;
            case R.id.left:
                edit.setText(edit.getText() + "(");
                Clean.setText("C");
                now = false;
                break;
            case R.id.add:
                edit.setText(edit.getText() + "+");
                Clean.setText("C");
                now = false;
                break;
            case R.id.substact:
                edit.setText(edit.getText() + "-");
                Clean.setText("C");
                now = false;
                break;
            case R.id.multiply:
                edit.setText(edit.getText() + "×");
                Clean.setText("C");
                now = false;
                break;
            case R.id.divide:
                edit.setText(edit.getText() + "÷");
                Clean.setText("C");
                now = false;
                break;
            case R.id.equal:
                edit.setText(edit.getText() + "=");
                lasttext = edit.getText().toString();
                String a1 = String.valueOf(a.caculate(lasttext));
                view.setText(a1);
                break;
            //清楚操作,保留上一结果,引入计算部分
            case R.id.Clean:
                edit.setText("0");
                Clean.setText("C");
                now = true;
                //归零操作,不保留上一次结果
        }
    }

完成了连接部分,就是最核心的计算部分

3,计算部分(Formulautil.java)

import java.util.Stack;
import java.math.BigDecimal;


public class Formulautil {

    /**大致思路是利用栈的出栈入栈压栈来处理一个运算式的先后级排序,进行相映的运算.*/

    //数字栈:用于存储表达式中的各个数字
    private Stack numberStack = null;
    //符号栈:用于存储运算符和括号
    private Stack symbolStack = null;

    private int scale;//除法时出现循环小数保留精度
    public Formulautil(int scale) {
        super();
        this.scale = scale;
    }
    public Formulautil() {
        this(32);
    }

    /**从外面把字符串传递进来!!!*/
    public BigDecimal caculate(String numStr) {
        //判断算数表示是否结束,也就是判断结尾有木有=号!没有给加上!
        //equals方法:值的比较
        //charAt方法:检索方法
        if (numStr.length() > 1
                && !"=".equals(numStr.charAt(numStr.length() - 1) + "")) {
            numStr += "=";
        }
        //检查表达式是否是正确的!利用Standard方法(自定义)
        if (!isStandard(numStr)) {
            String isstandardtext;
            isstandardtext = "出错";
            return null;
        }
        // 初始化栈
        if (numberStack == null) {
            numberStack = new Stack();
        }
        numberStack.clear();
        if (symbolStack == null) {
            symbolStack = new Stack();
        }
        symbolStack.clear();

        /**!!!!!!!!!!核 心!!!!!!!!!!!!*/
        //创建一个StringBuffer,用来放多位的数字
        StringBuffer temp = new StringBuffer();
        // 从表达式的第一个字符开始处理
        for (int i = 0; i < numStr.length(); i++) {
            // 获取一个字符
            char ch = numStr.charAt(i);
            // 若当前字符是数字
            if (isNumber(ch)) {
                // 加入到数字缓存中
                temp.append(ch);
            } else { // 非数字的情况
                // 将数字缓存转为字符串
                String tempStr = temp.toString();
                if (!tempStr.isEmpty()) {
                    BigDecimal num = new BigDecimal(tempStr);
                    // 将数字压栈
                    numberStack.push(num);
                    // 重置数字缓存
                    temp = new StringBuffer();
                }

                // 判断运算符的优先级,若当前优先级低于栈顶的优先级,则先把计算前面计算出来
                while (!comparePri(ch) && !symbolStack.empty()) {
                    // 出栈,取出数字,后进先出
                    BigDecimal b = numberStack.pop();
                    BigDecimal a = numberStack.pop();
                    // 取出运算符进行相应运算,并把结果压栈进行下一次运算
                    switch ((char) symbolStack.pop()) {
                        case '+':
                            numberStack.push(a.add(b));
                            break;
                        case '-':
                            numberStack.push(a.subtract(b));
                            break;
                        case '×':
                            numberStack.push(a.multiply(b));
                            break;
                        case '÷':
                            try {
                                numberStack.push(a.divide(b));
                            } catch (java.lang.ArithmeticException e) {
                                // 进行除法出现无限循环小数时,就会抛异常,此处设置精度重新计算
                                numberStack.push(a.divide(b, this.scale,
                                        BigDecimal.ROUND_HALF_EVEN));
                            }
                            break;
                        default:
                            break;
                    }
                } // while循环结束

                if (ch != '=') {
                    // 符号入栈
                    symbolStack.push(new Character(ch));
                    // 去括号
                    if (ch == ')') {
                        symbolStack.pop();
                        symbolStack.pop();
                    }
                }
            }
        } // for循环结束

        // 返回计算结果
        return numberStack.pop();
    }


    /**=================================检查算数表达式是否合格======================================*/
    private boolean isStandard(String numStr) {
        // 表达式不能为空
        if (numStr == null || numStr.isEmpty())
            return false;
        // 用来保存括号,检查左右括号是否匹配
        Stack stack = new Stack();
        // 用来标记'='符号是否存在多个
        boolean b = false;
        for (int i = 0; i < numStr.length(); i++) {
            char n = numStr.charAt(i);
            // 判断字符是否合法
            if (!(isNumber(n) || "(".equals(n + "") || ")".equals(n + "")
                    || "+".equals(n + "") || "-".equals(n + "")
                    || "×".equals(n + "") || "÷".equals(n + "") || "=".equals(n
                    + ""))) {
                return false;
            }
            // 将左括号压栈,用来给后面的右括号进行匹配
            if ("(".equals(n + "")) {
                stack.push(n);
            }
            if (")".equals(n + "")) { // 匹配括号
                if (stack.isEmpty() || !"(".equals((char) stack.pop() + "")) // 括号是否匹配
                    return false;
            }
            // 检查是否有多个'='号
            if ("=".equals(n + "")) {
                if (b)
                    return false;
                b = true;
            }
        }
        // 可能会有缺少右括号的情况
        if (!stack.isEmpty())
            return false;
        // 检查'='号是否不在末尾
        if (!("=".equals(numStr.charAt(numStr.length() - 1) + "")))
            return false;
        return true;
    }

    /**=================================判断是否是0-9的数字========================================*/
    private boolean isNumber(char num) {
        if ((num >= '0' && num <= '9') || num == '.')
            return true;
        return false;
    }

    /**==============比较优先级,如果当前运算符比栈顶元素运算符优先级高则返回true,否则返回false==========*/
    private boolean comparePri(char symbol) {
        // 空栈返回ture
        if (symbolStack.empty()) {
            return true;
        }

        /*
         我设计得这个计算器加减乘除,lg,ln,括号,三角函数,正常得优先级就是有括号先算括号,然后再乘除,在加减
         第一级:(
         第二级: × ÷ sin cos tan lg ln
         第三级: + -
         第四级:)
         */

        // 查看堆栈顶部的对象
        char top = (char) symbolStack.peek();
        if (top == '(') {
            return true;
        }
        // 比较优先级
        switch (symbol) {
            case '(': // 优先级最高
                return true;
            // 优先级比'+'和'-'高
            case '×': {
                if (top == '+' || top == '-')
                    return true;
                else
                    return false;
            }
            // 优先级比'+''-'高
            case '÷':
                if (top == '+' || top == '-')
                    return true;
                else
                    return false;

            case '+':
                return false;
            case '-':
                return false;
            // 优先级最低
            case ')':
                return false;
            // 结束符
            case '=':
                return false;
            default:
                break;
        }
        return true;
    }

}

然后我们看看运行的结果
加法
在这里插入图片描述
减法
在这里插入图片描述
乘法
在这里插入图片描述
除法
在这里插入图片描述
有小数点的数字的加减乘除也可以运行
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
有一个地方就是EditText那里可以加上这么一句话

android:background="@null"

这样你的EditText就不会底下出现一条横线,看着比较舒适

本文参考链接

参考链接:
https://github.com/bestxiaoxiaoming-hm/AndroidStudio----java-

四,总结

以上就是一个Android Studio制作的简单计算器
作者:周楷津
原文链接:https://blog.csdn.net/HeimuZ/article/details/106716141

你可能感兴趣的:(Android,android)