實驗二 計算器

實驗二 UI設計(一)

實驗目的:

自主完成一個簡單APP的設計工作,綜合應用已經學到的Android UI設計技巧,重點注意合理使用佈局。

 

實驗要求:

1.     完成一個計算器的設計,可以以手機自帶的計算器爲參考。設計過程中,注意考慮界面的美觀性,不同機型的適應性,以及功能的完備性。

2.     注意結合Activity的生命週期,考慮不同情況下計算器的界面狀態。

3.      如有餘力,可以考慮實現一個高精度科學計算型的計算器。

代碼:

MainActivity.java

package com.example.walker.calculator;

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

import java.util.ArrayList;
import java.util.EmptyStackException;
import java.util.List;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class MainActivity extends AppCompatActivity {
    private int[] idNum = {R.id.txt0, R.id.txt1, R.id.txt2,
            R.id.txt3, R.id.txt4, R.id.txt5, R.id.txt6,
            R.id.txt7, R.id.txt8, R.id.txt9};  //數字Number輸入
    private int[] idCal = {R.id.txtPlus, R.id.txtMinus,
            R.id.txtMul, R.id.txtDiv, R.id.txtLeft,
            R.id.txtRight, R.id.txtDot};  //運算符
    private Button[] buttonsCal = new Button[idCal.length];
    private Button[] buttonsNum = new Button[idNum.length];
    private Button buttonEqu;   //=
    private Button buttonClear;  // AC
    private Button buttonDel;
    private EditText input;
    private EditText output;
    private static String Text;

    @Override
    /**
     * input爲輸入字符行,
     * output爲結果。
     */
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        input = (EditText) findViewById(R.id.input);
        input.setText("");
        //input.setEnabled(false);//禁止點擊
        output = (EditText) findViewById(R.id.output);
        output.setText("0");
        output.setEnabled(false);//禁止點擊
        buttonEqu = (Button) findViewById(R.id.txtIs);
        buttonEqu.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                output.setText(new Calculate(input.getText().toString()).str);
            }
        });
        //AC 按鈕監聽
        buttonClear = (Button) findViewById(R.id.txtClear);
        buttonClear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                input.setText("");
                output.setText("0");
            }
        });
        //DEL按鈕監聽
        buttonDel = (Button) findViewById(R.id.txtDel);

        buttonDel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if (!input.getText().toString().isEmpty()) {
                    Text = input.getText().toString();
                    Text = Text.substring(0, Text.length() - 1);
                    input.setText(Text);
                }
            }
        });
/**
 * 註冊單擊事件
 */
        for (int index = 0; index < idCal.length; index++) {
            //運算符
            buttonsCal[index] = (Button) findViewById(idCal[index]);
            buttonsCal[index].setOnClickListener(new CalOnClick(buttonsCal[index].getText().toString()));

        }
        for (int i = 0; i < idNum.length; i++) {
            //數字
            buttonsNum[i] = (Button) findViewById(idNum[i]);
            buttonsNum[i].setOnClickListener(new NumberOnClick(buttonsNum[i].getText().toString()));
        }


    }

    //繼承OnClick接口
    class NumberOnClick implements View.OnClickListener {
        String Msg;

        /**
         * @param msg 點擊按鈕傳入字符
         */
        public NumberOnClick(String msg) {
            Msg = msg;
        }

        @Override
        public void onClick(View v) {
            if (!output.getText().toString().equals("")) {
                input.setText("");
                output.setText("");
            }
            input.append(Msg);
        }
    }

    class CalOnClick implements View.OnClickListener {
        String Msg;
        String[] calSymbol = {"+", "-", "*", "/", "."};

        public CalOnClick(String msg) {

            Msg = msg;
        }

        @Override
        public void onClick(View v) {
            if (!output.getText().toString().equals("")) {
                input.setText("");
                output.setText("");
            }
            // 檢查是否運算符重複輸入
            for (int i = 0; i < calSymbol.length; i++) {
                if (Msg.equals(calSymbol[i])) {
                    if (input.getText().toString().split("")
                            [input.getText().toString().split("").length - 1].equals(calSymbol[i])) {
                        Msg = "";
                    }

                }
            }
            input.append(Msg);
        }
    }

    /**
     * 運算類,返回一個String結果
     */
    public class Calculate {
        public String s1;
        StringBuilder str;

        public Calculate(String m) {
            this.s1 = m;
            try {
                eval();
            } catch (Exception e) {
                str.delete(0, str.length());
                str.append("輸入格式錯誤!");
            }
        }

        /**
         * 中綴表達式轉後綴表達式
         * <p>
         * 遍歷中綴的list
         * 1、數字時,加入後綴list
         * 2、“(”時,壓棧
         * 3、 若爲 ')',則依次彈棧,把彈出的運算符加入後綴表達式中,直到出現'(';
         * 4、若爲運算符,對做如下處置
         * 1、如果棧爲空,則壓棧
         * 2、如果棧不爲空:
         * 1、stack.peek().equals("(")  則壓棧
         * 2、比較str和stack.peek()的優先級
         * 1、如果>,則運算符壓棧
         * 2、<=的情況:當棧不爲空時:
         * 1、stack.peek()是左括號,壓棧
         * 2、<=,把peek加入後綴表達式,彈棧
         * 3、>,把運算符壓棧,停止對棧的操作
         * 執行完棧的操作之後,還得判斷:如果棧爲空,運算符壓棧
         */
        public List<String> midToAfter(List<String> midList) throws EmptyStackException {
            List<String> afterList = new ArrayList<String>();
            Stack<String> stack = new Stack<String>();
            for (String str : midList) {
                int flag = this.matchWitch(str);
                switch (flag) {
                    case 7:
                        afterList.add(str);
                        break;
                    case 1:
                        stack.push(str);
                        break;
                    case 2:
                        String pop = stack.pop();
                        while (!pop.equals("(")) {
                            afterList.add(pop);
                            pop = stack.pop();
                        }
                        break;
                    default:
                        if (stack.isEmpty()) {
                            stack.push(str);
                            break;
                        } else {
                            if (stack.peek().equals("(")) {
                                stack.push(str);
                                break;
                            } else {
                                int ji1 = this.youxianji(str);
                                int ji2 = this.youxianji(stack.peek());
                                if (ji1 > ji2) {
                                    stack.push(str);
                                } else {
                                    while (!stack.isEmpty()) {
                                        String f = stack.peek();
                                        if (f.equals("(")) {
                                            stack.push(str);
                                            break;
                                        } else {
                                            if (this.youxianji(str) <= this.youxianji(f)) {
                                                afterList.add(f);
                                                stack.pop();
                                            } else {
                                                stack.push(str);
                                                break;
                                            }
                                        }
                                    }
                                    if (stack.isEmpty()) {
                                        stack.push(str);
                                    }
                                }
                                break;
                            }
                        }
                }
            }
            while (!stack.isEmpty()) {
                afterList.add(stack.pop());
            }
            StringBuffer sb = new StringBuffer();
            for (String s : afterList) {
                sb.append(s + " ");
            }
            //System.out.println(sb.toString());
            return afterList;
        }

        /**
         * 判斷運算符的優先級
         */
        public int youxianji(String str) {
            int result = 0;
            if (str.equals("+") || str.equals("-")) {
                result = 1;
            } else {
                result = 2;
            }
            return result;
        }

        /**
         * 判斷字符串屬於操作數、操作符還是括號
         */
        public int matchWitch(String s) {
            if (s.equals("(")) {
                return 1;
            } else if (s.equals(")")) {
                return 2;
            } else if (s.equals("+")) {
                return 3;
            } else if (s.equals("-")) {
                return 4;
            } else if (s.equals("*")) {
                return 5;
            } else if (s.equals("/")) {
                return 6;
            } else {
                return 7;
            }
        }

        /**
         * 計算a@b的簡單方法
         */
        public Double singleEval(Double pop2, Double pop1, String str) {
            Double value = 0.0;
            if (str.equals("+")) {
                value = pop2 + pop1;
            } else if (str.equals("-")) {
                value = pop2 - pop1;
            } else if (str.equals("*")) {
                value = pop2 * pop1;
            } else {
                value = pop2 / pop1;
            }
            return value;
        }

        private double result;

        public double getResult() {
            return result;
        }

        public void setResult(double result) {
            this.result = result;
        }

        private int state;

        public int getState() {
            return state;
        }

        public void setState(int state) {
            this.state = state;
        }

        public void countHouzhui(List<String> list) {
            str = new StringBuilder("");
            state = 0;
            result = 0;
            Stack<Double> stack = new Stack<Double>();
            for (String str : list) {
                int flag = this.matchWitch(str);
                switch (flag) {
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                        Double pop1 = stack.pop();
                        Double pop2 = stack.pop();
                        Double value = this.singleEval(pop2, pop1, str);
                        stack.push(value);
                        break;
                    default:
                        Double push = Double.parseDouble(str);
                        stack.push(push);
                        break;
                }
            }
            if (stack.isEmpty()) {
                state = 1;
            } else {
                result = stack.peek();
                str.append(stack.pop());
            }


        }

        public void eval() throws Exception {
            List<String> list = new ArrayList<String>();
            //匹配運算符、括號、整數、小數,注意-和*要加\\
            Pattern p = Pattern.compile("[+\\-/\\*()]|\\d+\\.?\\d*");
            Matcher m = p.matcher(s1);
            while (m.find()) {
                list.add(m.group());
            }
            List<String> afterList = this.midToAfter(list);
            this.countHouzhui(afterList);
        }


    }


}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="#EEF0EC"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.walker.calculator.MainActivity"
    android:weightSum="1">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.4"
        android:background="#3f3c3c"
        android:divider="@color/colorAccent"
        android:showDividers="middle"
        android:orientation="vertical">

        <EditText
            android:id="@+id/input"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="4"
            android:background="#F0F8FF"
            android:gravity="end"
            android:inputType="none"
            android:textColor="#000000"
            android:textSize="24sp" />

        <EditText
            android:id="@+id/output"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#F0F8FF"
            android:layout_weight="6"
            android:gravity="end"
            android:textColor="#000000"
            android:textSize="50sp" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.6"
        android:orientation="vertical"
        android:divider="#0a0a0a">



        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.2"
            android:orientation="horizontal"
            android:divider="#0a0a0a">

            <Button
                android:id="@+id/txtClear"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="AC"
                android:textColor="#d8169a"
                android:textSize="20sp" />


            <Button
                android:id="@+id/txtDel"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="del"
                android:textColor="#d8169a"
                android:textSize="20sp" />

            <Button
                android:id="@+id/txtLeft"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="(" />

            <Button
                android:id="@+id/txtRight"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text=")" />

            <Button
                android:id="@+id/txtDiv"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="/"
                android:textSize="20sp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.2"
            android:orientation="horizontal"
            android:divider="#0a0a0a">

            <Button
                android:id="@+id/txt9"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="9"
                android:textSize="20sp" />

            <Button
                android:id="@+id/txt8"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="8"
                android:textSize="20sp" />

            <Button
                android:id="@+id/txt7"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="7"
                android:textSize="20sp" />

            <Button
                android:id="@+id/txtMul"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="*"
                android:textSize="20sp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.2"
            android:orientation="horizontal"
            android:divider="#0a0a0a">

            <Button
                android:id="@+id/txt6"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="6"
                android:textSize="20sp" />

            <Button
                android:id="@+id/txt5"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="5"
                android:textSize="20sp" />

            <Button
                android:id="@+id/txt4"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="4"
                android:textSize="20sp" />

            <Button
                android:id="@+id/txtPlus"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="+"
                android:textSize="20sp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.2"
            android:orientation="horizontal"
            android:divider="#0a0a0a">

            <Button
                android:id="@+id/txt1"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="1"
                android:textSize="20sp" />

            <Button
                android:id="@+id/txt2"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="2"
                android:textSize="20sp" />

            <Button
                android:id="@+id/txt3"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="3"
                android:textSize="20sp" />

            <Button
                android:id="@+id/txtMinus"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="-"
                android:textSize="20sp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.2"
            android:orientation="horizontal"
            android:divider="#0a0a0a">

            <Button
                android:id="@+id/txt0"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="2"
                android:text="0"
                android:textSize="20sp" />

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

            <Button
                android:id="@+id/txtIs"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="="
                android:background="#df3f86"
                android:textSize="20sp"></Button>
        </LinearLayout>
    </LinearLayout>

</LinearLayout>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章