项目源码在文章最后。


这两天写了一个Android的计算器,现在整理一下思路与代码。

首先是功能需求分析:

1、数字我规定最长为九位,如果有小数点则加上小数点最长为十位

2、第二个参数输入时不允许为负数,但是先得出的结果为负数,可以再进行运算(比如:1-2=-1,结果显示的是-1,可以再运算,-1+2=1)

3、得出的结果如果大于等于10位,则把数据进行科学计数

4、科学计数的数据不能再进行运算,再按按钮会直接显示0或者当前按下的数字

5、进行连续运算时,会先计算先一个运算的结果,在把结果作为第一个参数进行下次运算(比如:1+2+3,当按下第二个加号的时候,会显示3+,先把前一个运算的结果算出来再进行下一个运算)

6、当除数为0时,显示 error

7、默认情况下,显示 0

8、是否进行运算过,判断是否按下过等于号,如果按下,显示了结果,再按数字则直接显示当前数字而不是在结果后添加这个数字


接下来是正式开始编写代码:

1、界面布局 (TableLayout 实现按钮排版 ,EditText 显示表达式或值)

2、初始化所有控件,以及为需要点击事件的控件绑定监听器

3、编写监听器事件逻辑代码

①当按下的是数字,先判断是否计算过

----是(按下过等号):把显示的文本改为当前按下的数字,计算过的标志设为false

----否(没按过等号):进行下一步判断,计算过的标志设为false

--------判断当前文本是否有科学计数

--------是(有科学计数的标志 e ):文本置为 0

--------判断文本是否只有一个 0

--------是(当前文本为 0):文本置为空

--------判断是否有运算符

--------是(包含运算符):取出运算符后的第二个参数,进行下一步判断

------------判断最后一个是否是运算符

------------是(文本最后一个是运算符号):则直接添加按下的数字

------------否(文本最后一个不是运算符号):进行下一步判断

----------------判断第二个参数的长度,包括小数点则可以为10位,不包括小数点只能为9位

--------否(不包含运算符):判断第一个参数(即整个文本)的长度,包括小数点则可以为10位,不包括小数点只能为9位


②当按下的是小数点,先判断是否计算过

----是(按下过等号):把文本改为 0. (数字 0 的后面有一个小数点),把计算过的标志位设为 false

----否(没按过等号):进行下一步判断,,把计算过的标志位设为 false

--------判断是否有运算符

--------是(包含运算符):取出第二个参数,判断长度是否超过,是:无操作,否:判断参数中是否已经有小数点,有:无操作,否,添加小数点

--------否(不包含运算符):判断第一个参数(即整个文本)的长度是否超过,是:无操作,否:判断参数中是否已经有小数点,有:无操作,否,添加小数点


③当按下的是特殊键(归零、回退、百分比)

----归零:直接把文本改为 0

----回退:判断文本是否是 error,是:文本改为 0,否:判断文本的长度,当文本的长度大于0时且不等于1时,文本删掉最后一个字符,文本长度为1时,文本改为 0

----百分比:判断文本是否是 error,是:无操作,否:判断是否是表达式,是:无操作,否:数字除百


④当按下的是运算符,判断当前的文本是否是科学计数

----是(文本是科学计数,包含 e):文本置 0

----否(文本不是科学计数,不包含 e):进行下一步判断,且第二个参数不为空

--------判断文本是否是表达式

--------是(是表达式,有两个参数):先得出结果,如果结果不是 error,添加上相应的运算符,如果结果是 error,无操作

--------否(不是表达式,可能是数字,也可能是数字后面带一个运算符):如果计算过的标志位为 true,改为 false,如果最后一个字符为其他运算符,则改为当前按下的运算符,如果最后一个不是当前按下的运算符,则添加改运算符


⑤当按下的是等号,判断当前文本是否是表达式

----是:判断包含的是哪种运算符,取出两个参数,如果第二个参数为空,则无操作,如果第二个参数不为空,则进行相应的计算,再把运算结果进行格式化,然后用正则表达式去掉多余的 0  。如果结果的长度大于10位,则把数字转换成科学计数


布局代码如下(activity_main.xml):

<?xml version="1.0" encoding="utf-8"?>                            


界面效果如下:


逻辑部分代码如下(MainActivity.java):


package com.ikok.calculator;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.EditText;public class MainActivity extends AppCompatActivity implements View.OnClickListener {    /**     * 数字     */    private Button num0;    private Button num1;    private Button num2;    private Button num3;    private Button num4;    private Button num5;    private Button num6;    private Button num7;    private Button num8;    private Button num9;    /**     * 运算符     */    private Button plus_btn;    private Button subtract_btn;    private Button multiply_btn;    private Button divide_btn;    private Button equal_btn;    /**     * 其他     */    private Button dot_btn;    private Button percent_btn;    private Button delete_btn;    private Button ac_btn;    /**     * 结果     */    private EditText mResultText;    /**     * 已经输入的字符     */    private String existedText = "";    /**     * 是否计算过     */    private boolean isCounted = false;    /**     * 以负号开头,且运算符不是是减号     * 例如:-21×2     */    private boolean startWithOperator = false;    /**     * 以负号开头,且运算符是减号     * 例如:-21-2     */    private boolean startWithSubtract = false;    /**     * 不以负号开头,且包含运算符     * 例如:21-2     */    private boolean noStartWithOperator = false;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();        initEvent();    }    /**     * 初始化控件     */    private void initView() {        /**         * 数字         */        num0 = (Button) findViewById(R.id.num_zero);        num1 = (Button) findViewById(R.id.num_one);        num2 = (Button) findViewById(R.id.num_two);        num3 = (Button) findViewById(R.id.num_three);        num4 = (Button) findViewById(R.id.num_four);        num5 = (Button) findViewById(R.id.num_five);        num6 = (Button) findViewById(R.id.num_six);        num7 = (Button) findViewById(R.id.num_seven);        num8 = (Button) findViewById(R.id.num_eight);        num9 = (Button) findViewById(R.id.num_nine);        /**         * 运算符         */        plus_btn = (Button) findViewById(R.id.plus_btn);        subtract_btn = (Button) findViewById(R.id.subtract_btn);        multiply_btn = (Button) findViewById(R.id.multiply_btn);        divide_btn = (Button) findViewById(R.id.divide_btn);        equal_btn = (Button) findViewById(R.id.equal_btn);        /**         * 其他         */        dot_btn = (Button) findViewById(R.id.dot_btn);        percent_btn = (Button) findViewById(R.id.percent_btn);        delete_btn = (Button) findViewById(R.id.delete_btn);        ac_btn = (Button) findViewById(R.id.ac_btn);        /**         * 结果         */        mResultText = (EditText) findViewById(R.id.result_text);        /**         * 已经输入的字符         */        existedText = mResultText.getText().toString();    }    /**     * 初始化事件     */    private void initEvent() {        num0.setOnClickListener(this);        num1.setOnClickListener(this);        num2.setOnClickListener(this);        num3.setOnClickListener(this);        num4.setOnClickListener(this);        num5.setOnClickListener(this);        num6.setOnClickListener(this);        num7.setOnClickListener(this);        num8.setOnClickListener(this);        num9.setOnClickListener(this);        plus_btn.setOnClickListener(this);        subtract_btn.setOnClickListener(this);        multiply_btn.setOnClickListener(this);        divide_btn.setOnClickListener(this);        equal_btn.setOnClickListener(this);        dot_btn.setOnClickListener(this);        percent_btn.setOnClickListener(this);        delete_btn.setOnClickListener(this);        ac_btn.setOnClickListener(this);    }    /**     * 点击事件     * @param v  点击的控件     */    @Override    public void onClick(View v) {        switch (v.getId()){            /**             * 数字             */            case R.id.num_zero:                existedText = isOverRange(existedText,"0");                break;            case R.id.num_one:                existedText = isOverRange(existedText,"1");                break;            case R.id.num_two:                existedText = isOverRange(existedText,"2");                break;            case R.id.num_three:                existedText = isOverRange(existedText,"3");                break;            case R.id.num_four:                existedText = isOverRange(existedText,"4");                break;            case R.id.num_five:                existedText = isOverRange(existedText,"5");                break;            case R.id.num_six:                existedText = isOverRange(existedText,"6");                break;            case R.id.num_seven:                existedText = isOverRange(existedText,"7");                break;            case R.id.num_eight:                existedText = isOverRange(existedText,"8");                break;            case R.id.num_nine:                existedText = isOverRange(existedText,"9");                break;            /**             * 运算符             */            case R.id.plus_btn:                /**                 * 判断已有的字符是否是科学计数                 * 是 置零                 * 否 进行下一步                 *                 * 判断表达式是否可以进行计算                 * 是 先计算再添加字符                 * 否 添加字符                 *                 * 判断计算后的字符是否是 error                 * 是 置零                 * 否 添加运算符                 */                if (!existedText.contains("e")) {                    if (judgeExpression()) {                        existedText = getResult();                        if (existedText.equals("error")){                        } else {                            existedText += "+";                        }                    } else {                        if (isCounted) {                            isCounted = false;                        }                        if ((existedText.substring(existedText.length() - 1)).equals("-")) {                            existedText = existedText.replace("-", "+");                        } else if ((existedText.substring(existedText.length() - 1)).equals("×")) {                            existedText = existedText.replace("×", "+");                        } else if ((existedText.substring(existedText.length() - 1)).equals("÷")) {                            existedText = existedText.replace("÷", "+");                        } else if (!(existedText.substring(existedText.length() - 1)).equals("+")) {                            existedText += "+";                        }                    }                } else {                    existedText = "0";                }                break;            case R.id.subtract_btn:                if (!existedText.contains("e")) {                    if (judgeExpression()) {                        existedText = getResult();                        if (existedText.equals("error")){                        } else {                            existedText += "-";                        }                    } else {                        if (isCounted) {                            isCounted = false;                        }                        if ((existedText.substring(existedText.length() - 1)).equals("+")) {//                    Log.d("Anonymous", "onClick: " + "进入减法方法");                            existedText = existedText.replace("+", "-");                        } else if ((existedText.substring(existedText.length() - 1)).equals("×")) {                            existedText = existedText.replace("×", "-");                        } else if ((existedText.substring(existedText.length() - 1)).equals("÷")) {                            existedText = existedText.replace("÷", "-");                        } else if (!(existedText.substring(existedText.length() - 1)).equals("-")) {                            existedText += "-";                        }                    }                } else {                    existedText = "0";                }                break;            case R.id.multiply_btn:                if (!existedText.contains("e")) {                    if (judgeExpression()) {                        existedText = getResult();                        if (existedText.equals("error")){                        } else {                            existedText += "×";                        }                    } else {                        if (isCounted) {                            isCounted = false;                        }                        if ((existedText.substring(existedText.length() - 1)).equals("+")) {                            existedText = existedText.replace("+", "×");                        } else if ((existedText.substring(existedText.length() - 1)).equals("-")) {                            existedText = existedText.replace("-", "×");                        } else if ((existedText.substring(existedText.length() - 1)).equals("÷")) {                            existedText = existedText.replace("÷", "×");                        } else if (!(existedText.substring(existedText.length() - 1)).equals("×")) {                            existedText += "×";                        }                    }                } else {                    existedText = "0";                }                break;            case R.id.divide_btn:                if (!existedText.contains("e")) {                    if (judgeExpression()) {                        existedText = getResult();                        if (existedText.equals("error")){                        } else {                            existedText += "÷";                        }                    } else {                        if (isCounted) {                            isCounted = false;                        }                        if ((existedText.substring(existedText.length() - 1)).equals("+")) {                            existedText = existedText.replace("+", "÷");                        } else if ((existedText.substring(existedText.length() - 1)).equals("-")) {                            existedText = existedText.replace("-", "÷");                        } else if ((existedText.substring(existedText.length() - 1)).equals("×")) {                            existedText = existedText.replace("×", "÷");                        } else if (!(existedText.substring(existedText.length() - 1)).equals("÷")) {                            existedText += "÷";                        }                    }                } else {                    existedText = "0";                }                break;            case R.id.equal_btn:                existedText = getResult();                isCounted = true;                break;            /**             * 其他             */            case R.id.dot_btn:                /**                 * 判断是否运算过                 * 否                 *   判断是否有运算符,有 判断运算符之后的数字,无 判断整个数字                 *   判断数字是否过长,是则不能添加小数点,否则可以添加                 *   判断已经存在的数字里是否有小数点                 * 是                 *   字符串置为 0.                 */                if (!isCounted){                    if (existedText.contains("+") || existedText.contains("-") ||                            existedText.contains("×") || existedText.contains("÷") ){                        String param1 = null;                        String param2 = null;                        if (existedText.contains("+")) {                            param1 = existedText.substring(0, existedText.indexOf("+"));                            param2 = existedText.substring(existedText.indexOf("+") + 1);                        } else if (existedText.contains("-")) {                            param1 = existedText.substring(0, existedText.indexOf("-"));                            param2 = existedText.substring(existedText.indexOf("-") + 1);                        } else if (existedText.contains("×")) {                            param1 = existedText.substring(0, existedText.indexOf("×"));                            param2 = existedText.substring(existedText.indexOf("×") + 1);                        } else if (existedText.contains("÷")) {                            param1 = existedText.substring(0, existedText.indexOf("÷"));                            param2 = existedText.substring(existedText.indexOf("÷") + 1);                        }                        Log.d("Anonymous param1",param1);                        Log.d("Anonymous param2",param2);                        boolean isContainedDot = param2.contains(".");                        if (param2.length() >= 9){                        } else if (!isContainedDot){                            if (param2.equals("")){                                existedText += "0.";                            } else {                                existedText += ".";                            }                        } else {                            return;                        }                    } else {                        boolean isContainedDot = existedText.contains(".");                        if (existedText.length() >= 9){                        } else if (!isContainedDot){                            existedText += ".";                        } else {                            return;                        }                    }                    isCounted = false;                } else {                    existedText = "0.";                    isCounted = false;                }                break;            case R.id.percent_btn:                /**                 * 判断数字是否有运算符                 * 是 不做任何操作                 * 否 进行下一步                 *                 * 判断数字是否是 0                 * 是 不做任何操作                 * 否 进行除百                 *                 * 将字符串转换成double类型,进行运算后,再转换成String型                 */                if (existedText.equals("error")){                } else {                    getCondition();                    if (startWithOperator || startWithSubtract || noStartWithOperator) {                    } else {                        if (existedText.equals("0")) {                            return;                        } else {                            double temp = Double.parseDouble(existedText);                            temp = temp / 100;                            existedText = String.valueOf(temp);                        }                    }                }                break;            case R.id.delete_btn:                /**                 * 字符串长度大于 0 时才截取字符串                 * 如果长度为 1,则直接把字符串设置为 0                 */                if (existedText.equals("error")){                    existedText = "0";                } else if (existedText.length() > 0){                    if (existedText.length() == 1) {                        existedText = "0";                    } else {                        existedText = existedText.substring(0,existedText.length()-1);                    }                }                break;            case R.id.ac_btn:                existedText = "0";                break;        }        /**         * 设置显示         */        mResultText.setText(existedText);    }    /**     * 进行运算,得到结果     * @return  返回结果     */    private String getResult() {        /**         * 结果         */        String tempResult = null;        /**         * 两个String类型的参数         */        String param1 = null;        String param2 = null;        /**         * 转换后的两个double类型的参数         */        double arg1 = 0;        double arg2 = 0;        double result = 0;        getCondition();        /**         * 如果有运算符,则进行运算         * 没有运算符,则把已经存在的数据再传出去         */        if ( startWithOperator || noStartWithOperator || startWithSubtract) {            if (existedText.contains("+")) {                /**                 * 先获取两个参数                 */                param1 = existedText.substring(0, existedText.indexOf("+"));                param2 = existedText.substring(existedText.indexOf("+") + 1);                /**                 * 如果第二个参数为空,则还是显示当前字符                 */                if (param2.equals("")){                    tempResult = existedText;                } else {                    /**                     * 转换String为Double                     * 计算后再转换成String类型                     * 进行正则表达式处理                     */                    arg1 = Double.parseDouble(param1);                    arg2 = Double.parseDouble(param2);                    result = arg1 + arg2;                    tempResult = String.format("%f", result);                    tempResult = subZeroAndDot(tempResult);                }            } else if (existedText.contains("×")) {                param1 = existedText.substring(0, existedText.indexOf("×"));                param2 = existedText.substring(existedText.indexOf("×") + 1);                if (param2.equals("")){                    tempResult = existedText;                } else {                    arg1 = Double.parseDouble(param1);                    arg2 = Double.parseDouble(param2);                    result = arg1 * arg2;                    tempResult = String.format("%f", result);                    tempResult = subZeroAndDot(tempResult);                }            } else if (existedText.contains("÷")) {                param1 = existedText.substring(0, existedText.indexOf("÷"));                param2 = existedText.substring(existedText.indexOf("÷") + 1);                if (param2.equals("0")){                    tempResult = "error";                } else if (param2.equals("")){                    tempResult = existedText;                } else {                    arg1 = Double.parseDouble(param1);                    arg2 = Double.parseDouble(param2);                    result = arg1 / arg2;                    tempResult = String.format("%f", result);                    tempResult = subZeroAndDot(tempResult);                }            } else if (existedText.contains("-")) {                /**                 * 这里是以最后一个 - 号为分隔去取出两个参数                 * 进到这个方法,必须满足有运算公式                 * 而又避免了第一个参数是负数的情况                 */                param1 = existedText.substring(0, existedText.lastIndexOf("-"));                param2 = existedText.substring(existedText.lastIndexOf("-") + 1);                if (param2.equals("")){                    tempResult = existedText;                } else {                    arg1 = Double.parseDouble(param1);                    arg2 = Double.parseDouble(param2);                    result = arg1 - arg2;                    tempResult = String.format("%f", result);                    tempResult = subZeroAndDot(tempResult);                }            }            /**             * 如果数据长度大于等于10位,进行科学计数             *             * 如果有小数点,再判断小数点前是否有十个数字,有则进行科学计数             */            if (tempResult.length() >= 10) {                tempResult = String.format("%e", Double.parseDouble(tempResult));            } else if (tempResult.contains(".")) {                if (tempResult.substring(0, tempResult.indexOf(".")).length() >= 10) {                    tempResult = String.format("%e", Double.parseDouble(tempResult));                }            }        } else {            tempResult = existedText;        }        return tempResult;    }    /**     * 先判断是否按过等于号     * 是 按数字则显示当前数字     * 否 在已有的表达式后添加字符     *     * 判断数字是否就是一个 0     * 是 把字符串设置为空字符串。     *   1、打开界面没有运算过的时候,AC键归零或删除完归零的时候,会显示一个 0     *   2、当数字是 0 的时候,设置成空字符串,再按 0 ,数字会还是 0,不然可以按出 000 这种数字     * 否 添加按下的键的字符     *     * 判断数字是否包含小数点     * 是 数字不能超过十位     * 否 数字不能超过九位     *     * 进行上面的判断后,再判断数字是否超过长度限制     * 超过不做任何操作     * 没超过可以再添数字     */    private String isOverRange(String existedText, String s) {        /**         * 判断是否计算过         */        if (!isCounted){            /**             * 判断是否是科学计数             * 是 文本置零             */            if (existedText.contains("e")){                existedText = "0";            }            /**             * 判断是否只有一个 0             * 是 文本清空             */            if (existedText.equals("0")){                existedText = "";            }            /**             * 判断是否有运算符             * 是 判断第二个数字             * 否 判断整个字符串             */            if (existedText.contains("+") || existedText.contains("-") ||                    existedText.contains("×") || existedText.contains("÷")){                /**                 * 包括运算符时 两个数字 判断第二个数字                 * 两个参数                 */                String param2 = null;                if (existedText.contains("+")){                    param2 = existedText.substring(existedText.indexOf("+")+1);                } else if (existedText.contains("-")){                    param2 = existedText.substring(existedText.indexOf("-")+1);                } else if (existedText.contains("×")){                    param2 = existedText.substring(existedText.indexOf("×")+1);                } else if (existedText.contains("÷")){                    param2 = existedText.substring(existedText.indexOf("÷")+1);                }//            Log.d("Anonymous param1",param1);//            Log.d("Anonymous param2",param2);                if (existedText.substring(existedText.length()-1).equals("+") ||                        existedText.substring(existedText.length()-1).equals("-") ||                        existedText.substring(existedText.length()-1).equals("×") ||                        existedText.substring(existedText.length()-1).equals("÷")){                    existedText += s;                } else {                    if (param2.contains(".")){                        if (param2.length() >= 10){                        } else {                            existedText += s;                        }                    } else {                        if (param2.length() >= 9){                        } else {                            existedText += s;                        }                    }                }            } else {                /**                 * 不包括运算符时 一个数字                 */                if (existedText.contains(".")){                    if (existedText.length() >= 10){                    } else {                        existedText += s;                    }                } else {                    if (existedText.length() >= 9){                    } else {                        existedText += s;                    }                }            }            isCounted = false;        } else {            existedText = s;            isCounted = false;        }        return existedText;    }    /**     * 使用java正则表达式去掉多余的.与0     * @param s 传入的字符串     * @return 修改之后的字符串     */    public static String subZeroAndDot(String s){        if(s.indexOf(".") > 0){            s = s.replaceAll("0+?$", "");//去掉多余的0            s = s.replaceAll("[.]$", "");//如最后一位是.则去掉        }        return s;    }    /**     * 判断表达式     *     * 为了按等号是否进行运算     * 以及出现两个运算符(第一个参数如果为负数的符号不计)先进行运算再添加运算符     */    private boolean judgeExpression() {        getCondition();        String tempParam2 = null;        if ( startWithOperator || noStartWithOperator || startWithSubtract) {            if (existedText.contains("+")) {                /**                 * 先获取第二个参数                 */                tempParam2 = existedText.substring(existedText.indexOf("+") + 1);                /**                 * 如果第二个参数为空,表达式不成立                 */                if (tempParam2.equals("")) {                    return false;                } else {                    return true;                }            } else if (existedText.contains("×")) {                tempParam2 = existedText.substring(existedText.indexOf("×") + 1);                if (tempParam2.equals("")) {                    return false;                } else {                    return true;                }            } else if (existedText.contains("÷")) {                tempParam2 = existedText.substring(existedText.indexOf("÷") + 1);                if (tempParam2.equals("")) {                    return false;                } else {                    return true;                }            } else if (existedText.contains("-")) {                /**                 * 这里是以最后一个 - 号为分隔去取出两个参数                 * 进到这个方法,必须满足有运算公式                 * 而又避免了第一个参数是负数的情况                 */                tempParam2 = existedText.substring(existedText.lastIndexOf("-") + 1);                if (tempParam2.equals("")) {                    return false;                } else {                    return true;                }            }        }        return false;    }    /**     * 取得判断条件     */    private void getCondition() {        /**         * 以负号开头,且运算符不是是减号         * 例如:-21×2         */        startWithOperator = existedText.startsWith("-") && ( existedText.contains("+") ||                existedText.contains("×") || existedText.contains("÷") );        /**         * 以负号开头,且运算符是减号         * 例如:-21-2         */        startWithSubtract = existedText.startsWith("-") && ( existedText.lastIndexOf("-") != 0 );        /**         * 不以负号开头,且包含运算符         * 例如:21-2         */        noStartWithOperator = !existedText.startsWith("-") && ( existedText.contains("+") ||                existedText.contains("-") || existedText.contains("×") || existedText.contains("÷"));    }}


运行效果如下:





项目地址在:https://github.com/someonexiaole/Android

Calculator 即是。




更多相关文章

  1. 在Android中,如何判断当前是否在桌面上
  2. Android判断是否合法包名、是否系统应用
  3. 如何查看Android设备中的启动服务
  4. Android小游戏-数独(附源码)
  5. Android(安卓)密码校验,字符串中必须包含字母或者数字
  6. Android实现再图标右上角显示数字
  7. Android判断、创建和删除快捷方式
  8. FAQ_10_EditText与parseInt方法
  9. 在Android中如何通过点击edittext之外的部分使软键盘隐藏

随机推荐

  1. 软键盘弹出挤压画面的问题
  2. Kotlin Multiplatform - 下一代全平台开
  3. 背景透明的 Dialog
  4. android IPC通信(下)-AIDL
  5. Android FloatingActionButton 重要的操
  6. Android异步操作UI界面的四种方法(载至网
  7. eclipse:运行 Android 项目时出现 “Unabl
  8. 学到一点,做技术忌浮躁!
  9. 打包Android报错:Error building Player:
  10. 通过adb工具查看android sqlite3数据库