Android: 實現一個計算器 -- (四則運算)


計算器的功能介紹:

Name: Dot   (從某點開始,到某點結束)
功能:  + 、- 、* 、/ 、%
      (清零,退格操作)
版本:1.0

Dot 的效果展示:

侃侃 Dot:

Dot 與其他的計算器相比沒有太大的競爭力,甚至在處理一些極端的問題時還存在很大的不足,
例如:大數的四則運算,對於這個問題處理的還不夠到位,目前只能實現一些簡單的四則運算
(只能說自己的水平太菜,還沒有掌握一些實質性的內容,這個是自己需要檢討的)
另外:
非常感謝 Android 老師教給我們的知識,使我們可以設計出第一款屬於自己的 app.

改進的地方:

相對於最原始的設計,更新了哪些東西呢?
1、改變按鈕的形狀,由原始的長方形 -- 橢圓狀,使得按鈕更加形象化。
2、增加背景圖片,使用戶的體驗效果更好。
3、增加退格操作,使得用戶在輸錯信息時不用全盤清零,可以刪除剛剛寫的某個字符。

不足的地方:

1、未實現一些大數的運算。
2、當退格退完后,再按退格時會自動退出(不影響總體效果,但還是有那么一點 bug)
3、目前兩個數操作就需要 '=' 一下,但是可以實現多項式的運算,只是每次都需要 '='
   (后續會進行修改,逐漸完善)

補充知識:

android 中的事件處理步驟

a、找到事件目標對象(Button),通過 findViewById(),遍歷子對象。
b、實現view.onClickLisenter接口,重寫 onClick 方法。
c、在事件目標對象上注冊,btn.setOnClickListener(實現類的對象)

如何將信息顯示到 View(EditText)上:

a、為 EditText 定義 id -- etResult
b、通過 findViewById 獲取 etResult 對象
c、通過 etResult.setText() 將信息顯示到計算器界面上

異常的類型:

a、RuntimeException
運行時異常,不要求處理(但最好處理一下),與業務相關,比較主觀(每個應用都可以采用
自己的方式進行處理),一般不嚴重, 對效果不會產生太大的影響。
b、Checked Exception:
檢查異常,必須處理,非業務類型的錯誤,比較客觀,比較嚴重,會影響程序的執行。	

代碼部分:

calculate_layout.xml:

在 layout 里面新建一個文件calculate_layout.xml(布局類型是 GridLayout)
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:rowCount="6"
    android:columnCount="1"
    android:orientation="horizontal"
    android:id="@+id/gridlayout"
    android:background="@mipmap/bg">

    <EditText android:hint="Welcome"
        android:id="@+id/edResult"
        android:background="#2FC6CAC2"
        android:textColor="#3949AB"
        android:textColorHint="#3949AB"
        android:layout_gravity="fill_horizontal"
        android:gravity="right"
        android:paddingBottom="24dp"
        android:paddingTop="24dp"
        android:textSize="30sp"
        />

    <!--    使用 線性布局實現按鈕的等比例比重分配,每一行的按鈕為一組-->
    <LinearLayout android:layout_gravity="fill_horizontal">
        <Button
            android:text="AC"
            android:textSize="20sp"
            android:textColor="#E61111"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_marginTop="8dp"
            android:background="@drawable/yuanbtn"
            />

        <Button
            android:text="Del"
            android:textSize="20sp"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_marginTop="8dp"
            android:background="@drawable/yuanbtn"
            />
        <Button
            android:text="+/-"
            android:textSize="20sp"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_marginTop="8dp"
            android:background="@drawable/yuanbtn"/>
        <Button android:text="/"
            android:textSize="20sp"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_marginTop="8dp"
            android:background="@drawable/yuanbtn"/>
    </LinearLayout>
    <LinearLayout android:layout_gravity="fill_horizontal">
        <Button android:text="7"
            android:textSize="20sp"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_marginTop="8dp"
            android:background="@drawable/yuanbtn"/>
        <Button android:text="8"
            android:textSize="20sp"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_marginTop="8dp"
            android:background="@drawable/yuanbtn"/>
        <Button android:text="9"
            android:textSize="20sp"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_marginTop="8dp"
            android:background="@drawable/yuanbtn"/>
        <Button android:text="*"
            android:textSize="20sp"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_marginTop="8dp"
            android:background="@drawable/yuanbtn"/>
    </LinearLayout>
    <LinearLayout android:layout_gravity="fill_horizontal">
        <Button android:text="4"
            android:textSize="20sp"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_marginTop="8dp"
            android:background="@drawable/yuanbtn"/>
        <Button android:text="5"
            android:textSize="20sp"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_marginTop="8dp"
            android:background="@drawable/yuanbtn"/>
        <Button android:text="6"
            android:textSize="20sp"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_marginTop="8dp"
            android:background="@drawable/yuanbtn"/>
        <Button android:text="-"
            android:textSize="20sp"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_marginTop="8dp"
            android:background="@drawable/yuanbtn"/>
    </LinearLayout>
    <LinearLayout android:layout_gravity="fill_horizontal">
        <Button android:text="1"
            android:textSize="20sp"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_marginTop="8dp"
            android:background="@drawable/yuanbtn"/>
        <Button android:text="2"
            android:textSize="20sp"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_marginTop="8dp"
            android:background="@drawable/yuanbtn"/>
        <Button
            android:text = "3"
            android:textSize="20sp"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_marginTop="8dp"
            android:background="@drawable/yuanbtn"

            />
        <Button
            android:text = "+"
            android:textSize="20sp"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_marginTop="8dp"
            android:background="@drawable/yuanbtn"

            />
    </LinearLayout>
    <LinearLayout android:layout_gravity="fill_horizontal">
        <Button
            android:text = "%"
            android:textSize="20sp"
            android:id="@+id/btn_1"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_marginTop="8dp"
            android:background="@drawable/yuanbtn"

            />
        <Button
            android:text = "0"
            android:textSize="20sp"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_marginTop="8dp"
            android:background="@drawable/yuanbtn"

            />
        <Button
            android:text = "."
            android:textSize="20sp"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_marginTop="8dp"
            android:background="@drawable/yuanbtn"

            />
        <Button
            android:text = "="
            android:textColor="#039BE5"
            android:textSize="20sp"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_marginTop="8dp"
            android:background="@drawable/yuanbtn"
            />
    </LinearLayout>
</GridLayout>

yuanbtn.xml:

在drawable 文件夾下新建一個yuanbtn.xml文件,用來實現橢圓形的按鈕。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">


    <item>
        <shape
            xmlns:android="http://schemas.android.com/apk/res/android"
            >
            <!-- 填充的顏色 -->
            <solid android:color="#DDCBCB" />
            <!-- 設置按鈕的四個角為弧形 -->
            <!-- android:radius 弧形的半徑 -->
            <corners android:radius="105dip"/>

            <!-- padding: Button 里面的文字與Button邊界的間隔 -->
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp"
                />
        </shape>
    </item>

</selector>

MainActivity.java

package com.example.second;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridLayout;
import android.widget.LinearLayout;

import androidx.appcompat.app.AppCompatActivity;

/*
*   程序代碼、布局文件、二者之間的關系?
*   程序代碼:處理邏輯
*   布局文件:設計界面的(UI)
*   相輔相成,為什么要這樣呢?
*       1、容易分工,代碼清晰
*       2、代碼復用
*   如何加載?
*       類似充氣(氣球 -- 原來是一個空白界面,然后各個組件組合起來形成一個 good View)
* */

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    GridLayout gridLayout;
    EditText edResult;         // 計算器的顯示界面

    protected void onCreate(Bundle savedInstanceState){
            super.onCreate(savedInstanceState);
            // R 相當於是一個總類(靜態 -- 全局),我們后面用到的 calculate_layout 相當於是其屬性,(都是我們自己寫的文件)
            // 加載布局文件、初始化布局對象,進行充氣
            setContentView(R.layout.calculate_layout);

            // 通過 id 找到我們想要進行操作的對象
            edResult = findViewById(R.id.edResult);

            gridLayout = findViewById(R.id.gridlayout);
            int rowSize = gridLayout.getChildCount();
            for (int i = 1; i < rowSize; i++) {
                LinearLayout view = (LinearLayout) gridLayout.getChildAt(i);
                int colSize = view.getChildCount();
                for (int j = 0; j < colSize; j++) {
                    // 此時 Button 是事件目標
                    Button button = (Button) view.getChildAt(j);
                    // 當我們點擊某個按鈕時就會觸發這個事件
                    button.setOnClickListener(this);
                }
            }
        }

        String currentNumber = "";   // 當前數字
        String previousNumber = "";  // 前一個數字
        String operator = "";        // 符號


        // 這里相當於是后台,前台通過客戶觸發某個按鈕,然后我們后台得到這個按鈕的內容
        // 進行相應的處理
        public void onClick(View view) {
            // view 此時是 事件源(事件的源頭) -- 參照的位置不一樣
            if(view instanceof Button) {
                // 向下進行強制轉換
                Button button = (Button)view;
                // 得到按鈕的內容
                String btnStr = button.getText().toString();
                Log.i("calculator__",btnStr);

                switch (btnStr) {
                    case "0":
                    case "1":
                    case "2":
                    case "3":
                    case "4":
                    case "5":
                    case "6":
                    case "7":
                    case "8":
                    case "9":
                    case ".":
                        // 字符串的拼接
                        currentNumber += btnStr;
                        // 將內容顯示到 EditText
                        edResult.setText(currentNumber);
                        break;
                    case"+":
                        operator = btnStr;
                        previousNumber = currentNumber;
                        currentNumber = "";
                        break;
                    case"-":
                        operator = btnStr;
                        previousNumber = currentNumber;
                        currentNumber = "";
                        break;
                    case"*":
                        operator = btnStr;
                        previousNumber = currentNumber;
                        currentNumber = "";
                        break;
                    case"/":
                        operator = btnStr;
                        previousNumber = currentNumber;
                        currentNumber = "";
                        break;
                    case"%":
                        operator = btnStr;
                        previousNumber = currentNumber;
                        currentNumber = "";
                        break;
                    case"Del":
                        // 采用字符串截取的方式實現退格操作
                        currentNumber = currentNumber.substring(0,currentNumber.length() - 1);
                        edResult.setText(currentNumber);
                        break;
                    case"AC":
                        // 清空數據
                        operator = "";
                        currentNumber = "";
                        previousNumber = "";
                        edResult.setText("");
                        break;
                    case"=":
                        try{
                            double d1 = 0,d2 = 0,result = 0;
                            // RuntimeErron(運行時異常,最好進行異常處理)
                            d1 = Double.parseDouble(previousNumber);
                            d2 = Double.parseDouble(currentNumber);
                            switch (operator) {
                                case"+":
                                    result = d1 + d2;
                                    break;
                                case"-":
                                    result = d1 - d2;
                                    break;
                                case"*":
                                    result = d1 * d2;
                                    break;
                                case"/":
                                    result = d1 / d2;
                                    break;
                                case"%":
                                    result = d1 % d2;
                                    break;
                            }
                            currentNumber = result + "";
                            // 實現多項式計算
                            edResult.setText(currentNumber+"");
                        } catch(NumberFormatException e) {
                            // 打印錯誤信息
                            Log.i("calculate__",e.getMessage() + "");
                        }
                        break;
                }
            }
        }
}

實現效果:

多項式運算:

12 + 13 * 2 + 6 = 56(不放心可以在本地計算器上嘗試一下哦)

模運算(再次計算時要記得 AC 清空哦):

14 % 5 = 4

退格操作(可不是清空再輸入哦,哈哈,可以自己嘗試一下):

未退格之前:

退三格后(DEL 鍵):

后記:

本人也是初學者,這個設計還存在很多的不足,如果各位看官發現什么問題,希望提出來,
在下萬分感謝,同時,在瀏覽本文時遇到什么問題隨時私信我,或者在下面留言,大家共同
進步。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM