第一次寫博客嘿嘿嘿,很激動,記錄一下Android開發課第一次試驗——簡易計算器。
P.S.剛接觸Android Studio,純探索式完成,代碼以及內容有些粗糙QAQ
好啦,進入正題
首先是布局activity_main.xml文件,先上代碼:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<EditText
android:id="@+id/msg"
android:inputType="number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""
android:autofillHints="" tools:targetApi="o">
</EditText>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/clc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/clc"></Button>
<Button
android:id="@+id/mod"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/per"></Button>
<Button
android:id="@+id/div"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/div"></Button>
<Button
android:id="@+id/mul"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/mul"></Button>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/seven"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/seven"></Button>
<Button
android:id="@+id/eight"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/eight"></Button>
<Button
android:id="@+id/nine"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/nine"></Button>
<Button
android:id="@+id/sub"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/sub"></Button>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/four"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/four"></Button>
<Button
android:id="@+id/five"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/five"></Button>
<Button
android:id="@+id/six"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/six"></Button>
<Button
android:id="@+id/add"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/add"></Button>
</LinearLayout>
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false">
<LinearLayout android:orientation="vertical"
android:layout_weight="3"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/one"></Button>
<Button
android:id="@+id/two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/two"></Button>
<Button
android:id="@+id/three"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/borderlessButtonStyle"
android:text="@string/three"></Button>
</LinearLayout>
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/zero"
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="2"
style="?android:attr/borderlessButtonStyle"
android:text="@string/zero"></Button>
<Button
android:id="@+id/dot"
style="?android:attr/borderlessButtonStyle"
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/dot"></Button>
</LinearLayout>
</LinearLayout>
<LinearLayout android:orientation="vertical"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<Button
android:id="@+id/equ"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="?android:attr/borderlessButtonStyle"
android:text="@string/equ"></Button>
</LinearLayout>
</LinearLayout>
下面是MainActivity.java文件,主要分為四種鍵分開處理:C鍵(單個字符清除鍵),=鍵(EditText獲取所有表達式字符處理鍵),數字鍵以及操作符鍵:
首選是數字鍵(0~9),其主要實現把本身的value(activity中設置)傳給EditText顯示出來,由於代碼基本一致,就先放一個例子:
zero.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.append(zero.getText().toString());
}
});
其次是操作符鍵(+-*/.),其實現思路原本和數字鍵一樣,但是不知道為什么append方法不適用於這些操作符,有大佬知道原因的話,煩請告知啊QAQ,於是:
add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.setText(msg.getText()+"+");
}
});
之后是C(單個字符清除鍵),其思路是假設EditText中有n個字符,先取出n-1個字符,再把第n位用“ ”代替,代碼如下:
clc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int count=0;//記錄覆蓋的空格的個數,由於空格也計入字符串長度中,對下面的每次刪去的個數有影響,所以記錄並在下面減去
String s = msg.getText().toString();
for(int i=0;i<s.length();i++)
if((s.substring(i,i+1)==""))
count++;
//考慮邊界情況
if(count>=s.length()-1)
count = s.length()-1;
s = (String) s.subSequence(0,s.length()-1-count);
s = s.concat("");
msg.setText(s);
}
});
最后是=鍵(表達式處理得出結果鍵),其思路是把中綴表達式轉化成后綴表達式,在通過后綴表達式計算,代碼如下(代碼十分粗糙,由於只會C,不大會java,很多方法都是先查的QAQ):
equ.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int i = 0, j = 0, k = 0,count=1;//count 記錄小數點后面有幾位
char b;
String str=msg.getText().toString();
double data[] = new double[100];//模擬數字棧
String strr = "";//模擬操作符棧
//入棧
for (i = 0; i < str.length(); i++) {
count=1;
data[j]=0;
//首先判斷是都是數字,注意多位數的情況
while ((i < str.length()) && (str.substring(i, i + 1).equals("0") || str.substring(i, i + 1).equals("1") || str.substring(i, i + 1).equals("2") || str.substring(i, i + 1).equals("3") || str.substring(i, i + 1).equals("4") || str.substring(i, i + 1).equals("5") || str.substring(i, i + 1).equals("6") || str.substring(i, i + 1).equals("7") || str.substring(i, i + 1).equals("8") || str.substring(i, i + 1).equals("9")) && (j < 100)) {
data[j] = data[j] * 10 + Integer.parseInt(str.substring(i, i + 1));
i++;
}
j++;
//考慮操作數是小數的情況
if((i < str.length()) &&(str.substring(i,i+1).equals(".")))
{
i++;
j--;
while ((i < str.length()) && (str.substring(i, i + 1).equals("0") || str.substring(i, i + 1).equals("1") || str.substring(i, i + 1).equals("2") || str.substring(i, i + 1).equals("3") || str.substring(i, i + 1).equals("4") || str.substring(i, i + 1).equals("5") || str.substring(i, i + 1).equals("6") || str.substring(i, i + 1).equals("7") || str.substring(i, i + 1).equals("8") || str.substring(i, i + 1).equals("9")) && (j < 100)) {
data[j] = data[j] * 10 + Integer.parseInt(str.substring(i, i + 1));
i++;
count=count*10;
}
data[j]=data[j]*1.0/count;
j++;
System.out.println(data[j]);
}
if (i >= str.length()) break;
if ((k == 0)||(i<str.length())&&(pric(str.charAt(i)) >= pric(strr.charAt(k - 1)))) {
strr = strr.concat(str.substring(i, i + 1));
//System.out.println("strr:"+strr);
k++;
}
else {
//還要考慮一直大於的情況,一直字符串出棧
while (k >= 1 && (pric(str.charAt(i)) < pric(strr.charAt(k - 1)))) {
j--;
k--;
b = strr.charAt(k);
if (b == '+') data[j - 1] = add(data[j - 1], data[j]);
else if (b == '-') data[j - 1] = sub(data[j - 1], data[j]);
else if (b == '*') data[j - 1] = mul(data[j - 1], data[j]);
else if (b == '/') data[j - 1] = div(data[j - 1], data[j]);
}
strr = (String) strr.subSequence(0, k);
strr = strr.concat(str.substring(i, i + 1));
k++;
}
}
k--;
//出棧
while (k >= 0 && j >= 0) {
j--;
b = strr.charAt(k);
System.out.println("b:" + b);
if (b == '+') data[j - 1] = add(data[j - 1], data[j]);
else if (b == '-') data[j - 1] = sub(data[j - 1], data[j]);
else if (b == '*') data[j - 1] = mul(data[j - 1], data[j]);
else if (b == '/') data[j - 1] = div(data[j - 1], data[j]);
k--;
}
msg.setText(Double.toString(data[0]));
}
@org.jetbrains.annotations.Contract(pure = true)
private double add(double a, double b)
{
return a+b;
}
@org.jetbrains.annotations.Contract(pure = true)
private double sub(double a, double b)
{
return a-b;
}
@org.jetbrains.annotations.Contract(pure = true)
private double mul(double a, double b)
{
return a*b;
}
@org.jetbrains.annotations.Contract(pure = true)
private double div(double a, double b)
{
return a*1.0/b;
}
@org.jetbrains.annotations.Contract(pure = true)
private int pric(char a)
{
if(a=='+')return 1;
else if(a=='-')return 2;
else if(a=='*')return 3;
else if(a=='/')return 4;
return 0;
}
});
然后放一下MainActivity.java所有代碼:
private EditText msg;
private Button zero;
private Button one;
private Button two;
private Button three;
private Button four;
private Button five;
private Button six;
private Button seven;
private Button eight;
private Button nine;
private Button add;
private Button sub;
private Button mul;
private Button div;
private Button mod;
private Button dot;
private Button clc;
private Button equ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.msg = findViewById(R.id.msg);
this.zero = findViewById(R.id.zero);
this.one = findViewById(R.id.one);
this.two = findViewById(R.id.two);
this.three = findViewById(R.id.three);
this.four = findViewById(R.id.four);
this.five = findViewById(R.id.five);
this.six = findViewById(R.id.six);
this.seven = findViewById(R.id.seven);
this.eight = findViewById(R.id.eight);
this.nine = findViewById(R.id.nine);
this.add = findViewById(R.id.add);
this.sub = findViewById(R.id.sub);
this.mul = findViewById(R.id.mul);
this.div = findViewById(R.id.div);
this.equ = findViewById(R.id.equ);
this.clc = findViewById(R.id.clc);
this.dot = findViewById(R.id.dot);
zero.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.append(zero.getText().toString());
}
});
one.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.append(one.getText().toString());
}
});
two.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.append(two.getText().toString());
}
});
three.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.append(three.getText().toString());
}
});
four.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.append(four.getText().toString());
}
});
five.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.append(five.getText().toString());
}
});
six.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.append(six.getText().toString());
}
});
seven.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.append(seven.getText().toString());
}
});
eight.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.append(eight.getText().toString());
}
});
nine.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.append(nine.getText().toString());
}
});
add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.setText(msg.getText()+"+");
}
});
sub.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.setText(msg.getText()+"-");
}
});
mul.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.setText(msg.getText()+"*");
}
});
div.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.setText(msg.getText()+"/");
}
});
dot.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msg.setText(msg.getText()+".");
}
});
clc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int count=0;//記錄覆蓋的空格的個數
String s = msg.getText().toString();
for(int i=0;i<s.length();i++)
if((s.substring(i,i+1)==""))
count++;
if(count>=s.length()-1)
count = s.length()-1;
s = (String) s.subSequence(0,s.length()-1-count);
s = s.concat("");
msg.setText(s);
}
});
equ.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int i = 0, j = 0, k = 0,count=1;//count 記錄小數點后面有幾位
char b;
String str=msg.getText().toString();
double data[] = new double[100];//模擬數字棧
String strr = "";//模擬字符棧
//入棧
for (i = 0; i < str.length(); i++) {
count=1;
data[j]=0;
while ((i < str.length()) && (str.substring(i, i + 1).equals("0") || str.substring(i, i + 1).equals("1") || str.substring(i, i + 1).equals("2") || str.substring(i, i + 1).equals("3") || str.substring(i, i + 1).equals("4") || str.substring(i, i + 1).equals("5") || str.substring(i, i + 1).equals("6") || str.substring(i, i + 1).equals("7") || str.substring(i, i + 1).equals("8") || str.substring(i, i + 1).equals("9")) && (j < 100)) {
data[j] = data[j] * 10 + Integer.parseInt(str.substring(i, i + 1));
i++;
}//取數字保存在data中
j++;
if((i < str.length()) &&(str.substring(i,i+1).equals(".")))
{
i++;
j--;
while ((i < str.length()) && (str.substring(i, i + 1).equals("0") || str.substring(i, i + 1).equals("1") || str.substring(i, i + 1).equals("2") || str.substring(i, i + 1).equals("3") || str.substring(i, i + 1).equals("4") || str.substring(i, i + 1).equals("5") || str.substring(i, i + 1).equals("6") || str.substring(i, i + 1).equals("7") || str.substring(i, i + 1).equals("8") || str.substring(i, i + 1).equals("9")) && (j < 100)) {
data[j] = data[j] * 10 + Integer.parseInt(str.substring(i, i + 1));
i++;
count=count*10;
}//取數字保存在data中
data[j]=data[j]*1.0/count;
j++;
System.out.println(data[j]);
}
if (i >= str.length()) break;
if ((k == 0)||(i<str.length())&&(pric(str.charAt(i)) >= pric(strr.charAt(k - 1)))) {
strr = strr.concat(str.substring(i, i + 1));
k++;
}
else {//還要考慮一直大於的情況,一直字符串出棧
while (k >= 1 && (pric(str.charAt(i)) < pric(strr.charAt(k - 1)))) {
j--;
k--;
b = strr.charAt(k);
if (b == '+') data[j - 1] = add(data[j - 1], data[j]);
else if (b == '-') data[j - 1] = sub(data[j - 1], data[j]);
else if (b == '*') data[j - 1] = mul(data[j - 1], data[j]);
else if (b == '/') data[j - 1] = div(data[j - 1], data[j]);
}
strr = (String) strr.subSequence(0, k);
strr = strr.concat(str.substring(i, i + 1));
k++;
}
}
k--;
//出棧
while (k >= 0 && j >= 0) {
j--;
b = strr.charAt(k);
System.out.println("b:" + b);
if (b == '+') data[j - 1] = add(data[j - 1], data[j]);
else if (b == '-') data[j - 1] = sub(data[j - 1], data[j]);
else if (b == '*') data[j - 1] = mul(data[j - 1], data[j]);
else if (b == '/') data[j - 1] = div(data[j - 1], data[j]);
k--;
}
System.out.println(data[0]);
msg.setText(Double.toString(data[0]));
}
@org.jetbrains.annotations.Contract(pure = true)
private double add(double a, double b)
{
return a+b;
}
@org.jetbrains.annotations.Contract(pure = true)
private double sub(double a, double b)
{
return a-b;
}
@org.jetbrains.annotations.Contract(pure = true)
private double mul(double a, double b)
{
return a*b;
}
@org.jetbrains.annotations.Contract(pure = true)
private double div(double a, double b)
{
return a*1.0/b;
}
@org.jetbrains.annotations.Contract(pure = true)
private int pric(char a)
{
if(a=='+')return 1;
else if(a=='-')return 2;
else if(a=='*')return 3;
else if(a=='/')return 4;
return 0;
}
});
}
然后說一下這個計算器的BUG:
1.中綴轉后綴表達式的中間無法解決出現負數的情況,負數入棧還不知道怎么考慮
2.%雖然設計在上面也沒有考慮
其他暫時還未發現什么bug,有發現的同學告知一下哈!
最后強調一下Android Studio的Debug真的很好用,具體見博客:
https://blog.csdn.net/csdn_aiyang/article/details/79483848
好啦,結束啦!