第一個Android專案--簡易計算器的設計與實現
這個簡易計算器的實現我是參照慕課網上的視訊課程學習的,下面梳理我的開發過程以及DEBUG
在這個專案中實現計算器的第一步驟是對介面UI的設計,UI的設計並不難,一個總的Lnearlayout的佈局下orientation設定為vertical垂直分佈,然後此佈局下再設定1給我Edittext的一個文字框4個Lnearlayout子佈局(第4個佈局裡可以巢狀另外3個Lnearlayout的佈局來實現按鈕排版)這4個子佈局在你的介面上肯定是垂直分佈的,因為你的總佈局設定vertical。第一個子佈局放置4個Button,分別是C、DEL、/和*這4個功能按鈕,有一點是讓我比較開心的是,之前一直不知道一個按鈕或者一個邊框的橢圓形邊角如何設計出來,系統自帶邊框正正方方的感覺會有點死板,在Button屬性設定中有一個bachganoud設定,我們引用@drawable/btn_bg,這裡需要在drawable中新建1個XML的檔案,在這個XML檔案中設定總標籤<shape>,在這個標籤裡設定的<corners>就是對控制元件的邊角弧度設定,<solid>是對控制元件的背景填充,<stroke>是對控制元件的邊框以及邊框顏色設定。如果引用的是@drawable/btn_selector,那麼就需要新建兩個XML檔案,來實現這個按鈕點選前後的一個效果變化。剩下的子佈局不再贅述了,情況是類似的,有一點需要注意,需要通過margin這個屬性來控制各個子佈局的距離,為了介面不要太醜。
(UI介面實現)
UI介面實現後就是對計算器的邏輯實現了,首先在MainActivity中對各個控制元件進行繫結控制元件例項化,以及設定監聽事件,在這裡我是使用實現介面的方式來實現監聽事件事件,在控制元件數量比較多的情況下,這是一個不錯的選擇。
滑鼠點選事件Onclick()裡用了一個switch()結構用來識別究竟是點選了哪一個按鈕,設定一個變數String str=rt_input.get().toString()來獲取文字框裡的輸入資訊,對於case R. id. btn_0到case R.id.btn_point這些按鈕,當我們獲取到資訊後就可以直接輸出顯示了et_input.setText(str+(Button)v).getText());對於case R.id.btn_plus等加減乘除這些控制元件,為了和上面的數字按鈕區別開來,我們多設定兩個空格,下文會用的到,et_input.setText(str+“ ”+(Button)v).getText()+“ ”); 對於case R.id.btn_clean,我們直接設定輸出空值就好了et_input.setText(“”);對於case R.id.btn_del,由於需要一個個字元刪除,我們新增一個條件if(str!-null&&!str.epual("")){}設定成et_input.setText (str.substring (0, str. length()-1));意思是比原來的文字內容少一個字元顯示,嗯,就是這樣!最後一個case R.id.equal是我們邏輯實現的關鍵部門,它就是實現運算的,所以我們需要另外寫一個方法getResult()。、
在關鍵部分getResult()中,首先是也是需要獲取文字內容的String exp=rt_input.get().toString(),用於分離運算元和運算子。然後我們按照幾種輸入情況分別處理:情況一:輸入的值是空值或者沒有,可以直接返回。情況二:文字內容中沒有包含“ ”空格符,這是我們上文提到的空格符,和我們運算子繫結在一起了,這是因為沒有檢測到空格符,也就是沒有輸入運算子,只輸入的字元,也是直接返回。情況三:輸入的兩個運算元都不為空(之所以成為“簡易計算器”就是因為......它只實現兩個運算元之間的四則運算!哈哈),從這裡開始我們就要分離運算元和運算子了,採用substring(start,end)的方法分離,注意運算子前後還有空格需要考慮,我們這裡將運算元s1和s2強制轉換成double 型別。接著就是用if()結構對四則運算分別處理了,該加的加,該減的就減。最後再用一個if()結果,目的是如果兩個運算元同時是int型別的,我們再把結果輸出強制轉換成int 型別。情況四:運算元s1非空,而s2是空值,就直接輸出文字框中的內容。情況五:S1是空值,S2不為空值,s2強制轉換成double 型別,那麼該加減的就加減,該乘除的就輸出0,最後的輸出也是要用一個if()結構判斷一下的,如果是l兩個運算元是double,就直接輸出,如果是int ,就需要轉換一下。情況六:兩個運算元都空,直接輸出空et_input.setText("").
簡易計算器就設計完了!
但是......我的計算器仍然沒有能夠跑的起來,BUG始終存在呀,我們來DEBUG吧,首先我的程式一執行就出現閃退,根本來不及看見我設計的UI介面,後來看Log日誌,它說空指標異常,於是我去檢查程式碼,發現我一個控制元件btn_equal都沒有設定監聽事件,DEBUG之後程式可以運行了,但是新出現的問題就是點選“=”按鈕,功能無法實現,並且閃退,Log顯示是索引溢位,很納悶,檢查很多遍程式碼發現的錯誤是et_input.setText(str+“ ”+(Button)v).getText()+“ ”)中,我並沒有寫上空格:et_input.setText(str+“”+(Button)v) .getText()+“”),OK,這個錯誤也排除了,程式也不閃退了,但是邏輯運算功能還是沒實現,加減乘除通通不行,LOG顯示是分離運算元和運算子時出錯,我覺得一定是getResult()沒有處理好,然後一直檢查getResult(),沒有發現錯誤,還把教學視屏重複看了N遍,有點苦逼的,一天之後罵我重新再看整專案時想起來,當初設計UI是,為了數字在按鈕中顯示的位置比較合理好看,我在每個數值後面都添加了一個空格,android:text="1 ",就像這樣,怪不得運算元和運算子分離是會出現異常,怪自己奇葩挖坑......這個問題也解決了,整個程式就沒什麼大問題了,還有一點瑕疵:在進行完一次運算後,進行下一次運算,上次的結果還會停留在顯示框不會清零,這裡我們設定一個boolean值,在case的幾種按鈕中寫上if (clear_flag) {clear_flag = false;str = "";et_input.setText(""); }就可以了!
第一次Bolgs 記錄結束!下面把程式原始碼貼一下:
UI介面:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:layout_marginLeft="3dp"
android:layout_marginRight="3dp">
<EditText
android:layout_width="match_parent"
android:layout_height="60dp"
android:id="@+id/et_input"
android:editable="false"
android:background="@drawable/white_bg"
android:gravity="center_vertical|right" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
android:layout_marginTop="20dp">
<Button
android:layout_width="60dp"
android:layout_height="60dp"
android:id="@+id/btn_clean"
android:text="C"
android:textSize="20sp"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:gravity="bottom|right"
android:background="@drawable/btn_selector"
android:paddingBottom="10dp"
android:paddingRight="10dp"
/>
<Button
android:layout_width="60dp"
android:layout_height="60dp"
android:id="@+id/btn_del"
android:text="DEL"
android:textSize="20sp"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:gravity="bottom|right"
android:background="@drawable/btn_selector"
android:paddingBottom="10dp"
android:paddingRight="10dp"
/>
<Button
android:layout_width="60dp"
android:layout_height="60dp"
android:id="@+id/btn_divide"
android:text="/"
android:textSize="20sp"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:gravity="bottom|right"
android:background="@drawable/btn_selector"
android:paddingBottom="10dp"
android:paddingRight="10dp"/>
<Button
android:layout_width="60dp"
android:layout_height="60dp"
android:id="@+id/btn_multiplay"
android:text="*"
android:textSize="20sp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_weight="1"
android:gravity="bottom|right"
android:background="@drawable/btn_selector"
android:paddingBottom="10dp"
android:paddingRight="10dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
android:layout_marginTop="10dp">
<Button
android:layout_width="60dp"
android:layout_height="60dp"
android:id="@+id/btn_7"
android:text="7"
android:textSize="20sp"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:gravity="bottom|right"
android:background="@drawable/btn_selector"
android:paddingBottom="10dp"
android:paddingRight="10dp"/>
<Button
android:layout_width="60dp"
android:layout_height="60dp"
android:id="@+id/btn_8"
android:text="8"
android:textSize="20sp"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:gravity="bottom|right"
android:background="@drawable/btn_selector"
android:paddingBottom="10dp"
android:paddingRight="10dp"/>
<Button
android:layout_width="60dp"
android:layout_height="60dp"
android:id="@+id/btn_9"
android:text="9"
android:textSize="20sp"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:gravity="bottom|right"
android:background="@drawable/btn_selector"
android:paddingBottom="10dp"
android:paddingRight="10dp"/>
<Button
android:layout_width="60dp"
android:layout_height="60dp"
android:id="@+id/btn_minus"
android:text="-"
android:textSize="20sp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_weight="1"
android:gravity="bottom|right"
android:background="@drawable/btn_selector"
android:paddingBottom="10dp"
android:paddingRight="10dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
android:layout_marginTop="10dp">
<Button
android:layout_width="60dp"
android:layout_height="60dp"
android:id="@+id/btn_4"
android:text="4"
android:textSize="20sp"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:gravity="bottom|right"
android:background="@drawable/btn_selector"
android:paddingBottom="10dp"
android:paddingRight="10dp"/>
<Button
android:layout_width="60dp"
android:layout_height="60dp"
android:id="@+id/btn_5"
android:text="5"
android:textSize="20sp"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:gravity="bottom|right"
android:background="@drawable/btn_selector"
android:paddingBottom="10dp"
android:paddingRight="10dp"/>
<Button
android:layout_width="60dp"
android:layout_height="60dp"
android:id="@+id/btn_6"
android:text="6"
android:textSize="20sp"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:gravity="bottom|right"
android:background="@drawable/btn_selector"
android:paddingBottom="10dp"
android:paddingRight="10dp"/>
<Button
android:layout_width="60dp"
android:layout_height="60dp"
android:id="@+id/btn_plus"
android:text="+"
android:textSize="20sp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_weight="1"
android:gravity="bottom|right"
android:background="@drawable/btn_selector"
android:paddingBottom="10dp"
android:paddingRight="10dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="10dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="3"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Button
android:layout_width="60dp"
android:layout_height="60dp"
android:id="@+id/btn_1"
android:text="1"
android:textSize="20sp"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:gravity="bottom|right"
android:background="@drawable/btn_selector"
android:paddingBottom="10dp"
android:paddingRight="10dp"/>
<Button
android:layout_width="60dp"
android:layout_height="60dp"
android:id="@+id/btn_2"
android:text="2"
android:textSize="20sp"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:gravity="bottom|right"
android:background="@drawable/btn_selector"
android:paddingBottom="10dp"
android:paddingRight="10dp"/>
<Button
android:layout_width="60dp"
android:layout_height="60dp"
android:id="@+id/btn_3"
android:text="3"
android:textSize="20sp"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:gravity="bottom|right"
android:background="@drawable/btn_selector"
android:paddingBottom="10dp"
android:paddingRight="10dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp">
<Button
android:layout_width="60dp"
android:layout_height="60dp"
android:id="@+id/btn_0"
android:text="0"
android:textSize="20sp"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:gravity="bottom|right"
android:background="@drawable/btn_selector"
android:paddingBottom="10dp"
android:paddingRight="10dp"/>
<Button
android:layout_width="60dp"
android:layout_height="60dp"
android:id="@+id/btn_point"
android:text="."
android:textSize="20sp"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:gravity="bottom|right"
android:background="@drawable/btn_selector"
android:paddingBottom="10dp"
android:paddingRight="10dp"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
>
<Button
android:layout_width="60dp"
android:layout_height="130dp"
android:id="@+id/btn_equal"
android:text="="
android:textSize="20sp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_weight="1"
android:gravity="bottom|right"
android:background="@drawable/orange_selector"
android:paddingBottom="10dp"
android:paddingRight="10dp"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<span style="font-size:18px;">//按鈕點選後的樣式:</span>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="5dp"/>
<solid
android:color="@android:color/darker_gray"/>
<stroke
android:width="1dp"
android:color="@android:color/black"/>
</shape>
//按鈕點選前的樣式
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="5dp"/>
<!--<gradient-->
<!--android:startColor="@color/colorAccent"-->
<!--android:endColor="@color/colorAccent"/>-->
<solid
android:color="@android:color/white"/>
<stroke
android:width="1dp"
android:color="@android:color/black"/>
</shape>
//按鈕點選前後的變化實現
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/gray_btn" android:state_pressed="true"/>
<item android:drawable="@drawable/white_bg"/>
</selector>
MainActivity:package com.example.boss.calculator;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Button btn_0, btn_1, btn_2, btn_3, btn_4, btn_5,
btn_6, btn_7, btn_8, btn_9, btn_equal,
btn_point, btn_clean, btn_del, btn_plus,
btn_minus, btn_multiply, btn_divide;
EditText et_input;
boolean clear_flag;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_0 = (Button) findViewById(R.id.btn_0);
btn_1 = (Button) findViewById(R.id.btn_1);
btn_2 = (Button) findViewById(R.id.btn_2);
btn_3 = (Button) findViewById(R.id.btn_3);
btn_4 = (Button) findViewById(R.id.btn_4);
btn_5 = (Button) findViewById(R.id.btn_5);
btn_6 = (Button) findViewById(R.id.btn_6);
btn_7 = (Button) findViewById(R.id.btn_7);
btn_8 = (Button) findViewById(R.id.btn_8);
btn_9 = (Button) findViewById(R.id.btn_9);
btn_clean = (Button) findViewById(R.id.btn_clean);
btn_equal = (Button) findViewById(R.id.btn_equal);
btn_minus = (Button) findViewById(R.id.btn_minus);
btn_multiply = (Button) findViewById(R.id.btn_multiplay);
btn_plus = (Button) findViewById(R.id.btn_plus);
btn_point = (Button) findViewById(R.id.btn_point);
btn_del = (Button) findViewById(R.id.btn_del);
btn_divide = (Button) findViewById(R.id.btn_divide);
et_input = (EditText) findViewById(R.id.et_input);
btn_0.setOnClickListener(this);
btn_1.setOnClickListener(this);
btn_2.setOnClickListener(this);
btn_3.setOnClickListener(this);
btn_4.setOnClickListener(this);
btn_5.setOnClickListener(this);
btn_6.setOnClickListener(this);
btn_7.setOnClickListener(this);
btn_8.setOnClickListener(this);
btn_9.setOnClickListener(this);
btn_equal.setOnClickListener(this);
btn_minus.setOnClickListener(this);
btn_multiply.setOnClickListener(this);
btn_divide.setOnClickListener(this);
btn_del.setOnClickListener(this);
btn_point.setOnClickListener(this);
btn_plus.setOnClickListener(this);
btn_clean.setOnClickListener(this);
et_input.setOnClickListener(this);
}
@Override
public void onClick(View v) {
String str = et_input.getText().toString();
switch (v.getId()) {
case R.id.btn_0:
case R.id.btn_1:
case R.id.btn_2:
case R.id.btn_3:
case R.id.btn_4:
case R.id.btn_5:
case R.id.btn_6:
case R.id.btn_7:
case R.id.btn_8:
case R.id.btn_9:
case R.id.btn_point:
if (clear_flag) {
clear_flag = false;
str = "";
et_input.setText("");
}
et_input.setText(str + ((Button) v).getText());
break;
case R.id.btn_plus:
case R.id.btn_minus:
case R.id.btn_multiplay:
case R.id.btn_divide:
if (clear_flag) {
clear_flag = false;
str = "";
et_input.setText("");
}
et_input.setText(str + " " + ((Button) v).getText() + " ");
break;
case R.id.btn_clean:
clear_flag = false;
et_input.setText("");
break;
case R.id.btn_del:
if (clear_flag) {
clear_flag = false;
et_input.setText("");
} else if (str != null && !str.equals("")) {
et_input.setText(str.substring(0, str.length() - 1));
}
case R.id.btn_equal:
getResult();
break;
default:
break;
}
}
private void getResult() {
String exp = et_input.getText().toString();
if(exp==null||exp.equals("")){
return;
}
if(!exp.contains(" ")){
return;
}
if(clear_flag){
clear_flag=false;
return ;
}
clear_flag = true;
double result = 0;
String s1 = exp.substring(0, exp.indexOf(" "));
String op = exp.substring(exp.indexOf(" ") + 1, exp.indexOf(" ") + 2);
String s2 = exp.substring(exp.indexOf(" ") + 3);
if (!s1.equals("") && !s2.equals("")) {
double d1 = Double.parseDouble(s1);
double d2 = Double.parseDouble(s2);
if (op.equals("+")) {
result = d1 + d2;
} else if (op.equals("-")) {
result = d1 - d2;
} else if (op.equals("*")) {
result = d1 * d2;
} else if (op.equals("/")) {
if (d2 == 0) {
result = 0;
} else {
result = d1 / d2;
}
}
if (!s1.contains(".") && !s2.contains(".") && !op.equals("/")) {
int r = (int) result;
et_input.setText(r + "");
} else {
et_input.setText(result + "");
}
}
else if(!s1.equals("")&&s2.equals("")){
et_input.setText(exp);
}
else if(s1.equals("")&&!s2.equals("")){
double d2=Double.parseDouble(s2);
if(op.equals("+")){
result=0+d2;
}else if(op.equals("-")){
result=0-d2;
}else if(op.equals("*")){
result=0;
}else if(op.equals("/")){
result = 0;
}
if(!s2.contains(".")){
int r=(int) result;
et_input.setText(r+" ");
} else{
et_input.setText(result+" ");
}
}else{
et_input.setText("");
}
}
}