这个简易计算器的实现我是参照慕课网上的视频课程学习的,下面梳理我的开发过程以及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()。、
情况一:输入的值是空值或者没有,可以直接返回。情况二:文本内容中没有包含“ ”空格符,这是我们上文提到的空格符,和我们运算符绑定在一起了,这是因为没有检测到空格符,也就是没有输入运算符,只输入的字符,也是直接返回。情况三:输入的两个操作数都不为空(之所以成为“简易计算器”就是因为......它只实现两个操作数之间的四则运算!哈哈),从这里开始我们就要分离操作数和运算符了,采用substring(start,end)的方法分离,注意运算符前后还有空格需要考虑,我们这里将操作数s1和s2强制转换成double 类型。接着就是用if()结构对四则运算分别处理了,该加的加,该减的就减。最后再用一个if()结果,目的是如果两个操作数同时是int类型的,我们再把结果输出强制转换成int 类型。情况四:操作数s1非空,而s2是空值,就直接输出文本框中的内容。情况五:S1是空值,S2不为空值,s2强制转换成double 类型,那么该加减的就加减,该乘除的就输出0,最后的输出也是要用一个if()结构判断一下的,如果是l两个操作数是double,就直接输出,如果是int ,就需要转换一下。情况六:两个操作数都空,直接输出空et_input.setText("").
简易计算器就设计完了!
“ ”+(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界面:
1. <?xml version="1.0" encoding="utf-8"?>
2. <LinearLayout
3. "http://schemas.android.com/apk/res/android"
4. "http://schemas.android.com/tools"
5. "match_parent"
6. "match_parent"
7. "vertical"
8. ".MainActivity">
9.
10. <LinearLayout
11. "match_parent"
12. "wrap_content"
13. "50dp"
14. "3dp"
15. "3dp">
16. <EditText
17. "match_parent"
18. "60dp"
19. "@+id/et_input"
20. "false"
21. "@drawable/white_bg"
22. "center_vertical|right" />
23. </LinearLayout>
24. <LinearLayout
25. "match_parent"
26. "wrap_content"
27. "center"
28. "horizontal"
29. "20dp">
30.
31. <Button
32. "60dp"
33. "60dp"
34. "@+id/btn_clean"
35. "C"
36. "20sp"
37. "10dp"
38. "1"
39. "bottom|right"
40. "@drawable/btn_selector"
41. "10dp"
42. "10dp"
43.
44. />
45. <Button
46. "60dp"
47. "60dp"
48. "@+id/btn_del"
49. "DEL"
50. "20sp"
51. "10dp"
52. "1"
53. "bottom|right"
54. "@drawable/btn_selector"
55. "10dp"
56. "10dp"
57. />
58. <Button
59. "60dp"
60. "60dp"
61. "@+id/btn_divide"
62. "/"
63. "20sp"
64. "10dp"
65. "1"
66. "bottom|right"
67. "@drawable/btn_selector"
68. "10dp"
69. "10dp"/>
70. <Button
71. "60dp"
72. "60dp"
73. "@+id/btn_multiplay"
74. "*"
75. "20sp"
76. "10dp"
77. "10dp"
78. "1"
79. "bottom|right"
80. "@drawable/btn_selector"
81. "10dp"
82. "10dp"/>
83.
84. </LinearLayout>
85. <LinearLayout
86. "match_parent"
87. "wrap_content"
88. "center"
89. "horizontal"
90. "10dp">
91.
92. <Button
93. "60dp"
94. "60dp"
95. "@+id/btn_7"
96. "7"
97. "20sp"
98. "10dp"
99. "1"
100. "bottom|right"
101. "@drawable/btn_selector"
102. "10dp"
103. "10dp"/>
104. <Button
105. "60dp"
106. "60dp"
107. "@+id/btn_8"
108. "8"
109. "20sp"
110. "10dp"
111. "1"
112. "bottom|right"
113. "@drawable/btn_selector"
114. "10dp"
115. "10dp"/>
116. <Button
117. "60dp"
118. "60dp"
119. "@+id/btn_9"
120. "9"
121. "20sp"
122. "10dp"
123. "1"
124. "bottom|right"
125. "@drawable/btn_selector"
126. "10dp"
127. "10dp"/>
128. <Button
129. "60dp"
130. "60dp"
131. "@+id/btn_minus"
132. "-"
133. "20sp"
134. "10dp"
135. "10dp"
136. "1"
137. "bottom|right"
138. "@drawable/btn_selector"
139. "10dp"
140. "10dp"/>
141.
142. </LinearLayout>
143. <LinearLayout
144. "match_parent"
145. "wrap_content"
146. "center"
147. "horizontal"
148. "10dp">
149.
150. <Button
151. "60dp"
152. "60dp"
153. "@+id/btn_4"
154. "4"
155. "20sp"
156. "10dp"
157. "1"
158. "bottom|right"
159. "@drawable/btn_selector"
160. "10dp"
161. "10dp"/>
162. <Button
163. "60dp"
164. "60dp"
165. "@+id/btn_5"
166. "5"
167. "20sp"
168. "10dp"
169. "1"
170. "bottom|right"
171. "@drawable/btn_selector"
172. "10dp"
173. "10dp"/>
174. <Button
175. "60dp"
176. "60dp"
177. "@+id/btn_6"
178. "6"
179. "20sp"
180. "10dp"
181. "1"
182. "bottom|right"
183. "@drawable/btn_selector"
184. "10dp"
185. "10dp"/>
186. <Button
187. "60dp"
188. "60dp"
189. "@+id/btn_plus"
190. "+"
191. "20sp"
192. "10dp"
193. "10dp"
194. "1"
195. "bottom|right"
196. "@drawable/btn_selector"
197. "10dp"
198. "10dp"/>
199.
200. </LinearLayout>
201.
202. <LinearLayout
203. "match_parent"
204. "wrap_content"
205. "horizontal"
206. "10dp">
207. <LinearLayout
208. "wrap_content"
209. "match_parent"
210. "vertical"
211. "3"
212. >
213. <LinearLayout
214. "match_parent"
215. "wrap_content"
216. "horizontal"
217.
218. >
219. <Button
220. "60dp"
221. "60dp"
222. "@+id/btn_1"
223. "1"
224. "20sp"
225. "10dp"
226. "1"
227. "bottom|right"
228. "@drawable/btn_selector"
229. "10dp"
230. "10dp"/>
231. <Button
232. "60dp"
233. "60dp"
234. "@+id/btn_2"
235. "2"
236. "20sp"
237. "10dp"
238. "1"
239. "bottom|right"
240. "@drawable/btn_selector"
241. "10dp"
242. "10dp"/>
243. <Button
244. "60dp"
245. "60dp"
246. "@+id/btn_3"
247. "3"
248. "20sp"
249. "10dp"
250. "1"
251. "bottom|right"
252. "@drawable/btn_selector"
253. "10dp"
254. "10dp"/>
255. </LinearLayout>
256. <LinearLayout
257. "match_parent"
258. "wrap_content"
259. "10dp">
260. <Button
261. "60dp"
262. "60dp"
263. "@+id/btn_0"
264. "0"
265. "20sp"
266. "10dp"
267. "1"
268. "bottom|right"
269. "@drawable/btn_selector"
270. "10dp"
271. "10dp"/>
272. <Button
273. "60dp"
274. "60dp"
275. "@+id/btn_point"
276. "."
277. "20sp"
278. "10dp"
279. "1"
280. "bottom|right"
281. "@drawable/btn_selector"
282. "10dp"
283. "10dp"/>
284.
285. </LinearLayout>
286. </LinearLayout>
287. <LinearLayout
288. "wrap_content"
289. "wrap_content"
290. "1"
291. >
292. <Button
293. "60dp"
294. "130dp"
295. "@+id/btn_equal"
296. "="
297. "20sp"
298. "10dp"
299. "10dp"
300. "1"
301. "bottom|right"
302. "@drawable/orange_selector"
303. "10dp"
304. "10dp"/>
305.
306. </LinearLayout>
307.
308.
309.
310.
311. </LinearLayout>
312. </LinearLayout>
313.
314. <span style="font-size:18px;">//按钮点击后的样式:</span>
315. <?xml version="1.0" encoding="utf-8"?>
316. <shape xmlns:android="http://schemas.android.com/apk/res/android">
317. "5dp"/>
318. <solid
319. "@android:color/darker_gray"/>
320. <stroke
321. "1dp"
322. "@android:color/black"/>
323. </shape>
//按钮点击前的样式
1. <?xml version="1.0" encoding="utf-8"?>
2. <shape xmlns:android="http://schemas.android.com/apk/res/android">
3.
4. "5dp"/>
5. <!--<gradient-->
6. "@color/colorAccent"-->
7. "@color/colorAccent"/>-->
8. <solid
9. "@android:color/white"/>
10. <stroke
11. "1dp"
12. "@android:color/black"/>
13. </shape>
//按钮点击前后的变化实现
1. <?xml version="1.0" encoding="utf-8"?>
2. <selector xmlns:android="http://schemas.android.com/apk/res/android">
3. <item android:drawable="@drawable/gray_btn" android:state_pressed="true"/>
4. <item android:drawable="@drawable/white_bg"/>
5. </selector>
MainActivity:
1. package com.example.boss.calculator;
2.
3. import android.os.Bundle;
4. import android.support.v7.app.AppCompatActivity;
5. import android.view.View;
6. import android.widget.Button;
7. import android.widget.EditText;
8.
9. public class MainActivity extends AppCompatActivity implements View.OnClickListener {
10.
11. Button btn_0, btn_1, btn_2, btn_3, btn_4, btn_5,
12. btn_6, btn_7, btn_8, btn_9, btn_equal,
13. btn_point, btn_clean, btn_del, btn_plus,
14. btn_minus, btn_multiply, btn_divide;
15. EditText et_input;
16. boolean clear_flag;
17.
18. @Override
19. protected void onCreate(Bundle savedInstanceState) {
20. super.onCreate(savedInstanceState);
21. setContentView(R.layout.activity_main);
22. btn_0 = (Button) findViewById(R.id.btn_0);
23. btn_1 = (Button) findViewById(R.id.btn_1);
24. btn_2 = (Button) findViewById(R.id.btn_2);
25. btn_3 = (Button) findViewById(R.id.btn_3);
26. btn_4 = (Button) findViewById(R.id.btn_4);
27. btn_5 = (Button) findViewById(R.id.btn_5);
28. btn_6 = (Button) findViewById(R.id.btn_6);
29. btn_7 = (Button) findViewById(R.id.btn_7);
30. btn_8 = (Button) findViewById(R.id.btn_8);
31. btn_9 = (Button) findViewById(R.id.btn_9);
32. btn_clean = (Button) findViewById(R.id.btn_clean);
33. btn_equal = (Button) findViewById(R.id.btn_equal);
34. btn_minus = (Button) findViewById(R.id.btn_minus);
35. btn_multiply = (Button) findViewById(R.id.btn_multiplay);
36. btn_plus = (Button) findViewById(R.id.btn_plus);
37. btn_point = (Button) findViewById(R.id.btn_point);
38. btn_del = (Button) findViewById(R.id.btn_del);
39. btn_divide = (Button) findViewById(R.id.btn_divide);
40. et_input = (EditText) findViewById(R.id.et_input);
41. this);
42. this);
43. this);
44. this);
45. this);
46. this);
47. this);
48. this);
49. this);
50. this);
51. this);
52. this);
53. this);
54. this);
55. this);
56. this);
57. this);
58. this);
59. this);
60. }
61.
62. @Override
63. public void onClick(View v) {
64. String str = et_input.getText().toString();
65. switch (v.getId()) {
66. case R.id.btn_0:
67. case R.id.btn_1:
68. case R.id.btn_2:
69. case R.id.btn_3:
70. case R.id.btn_4:
71. case R.id.btn_5:
72. case R.id.btn_6:
73. case R.id.btn_7:
74. case R.id.btn_8:
75. case R.id.btn_9:
76. case R.id.btn_point:
77. if (clear_flag) {
78. false;
79. "";
80. "");
81. }
82. et_input.setText(str + ((Button) v).getText());
83. break;
84. case R.id.btn_plus:
85. case R.id.btn_minus:
86. case R.id.btn_multiplay:
87. case R.id.btn_divide:
88. if (clear_flag) {
89. false;
90. "";
91. "");
92. }
93. " " + ((Button) v).getText() + " ");
94. break;
95. case R.id.btn_clean:
96. false;
97.
98. "");
99. break;
100. case R.id.btn_del:
101. if (clear_flag) {
102. false;
103. "");
104. else if (str != null && !str.equals("")) {
105. 0, str.length() - 1));
106. }
107. case R.id.btn_equal:
108. getResult();
109. break;
110. default:
111. break;
112. }
113. }
114.
115. private void getResult() {
116. String exp = et_input.getText().toString();
117. if(exp==null||exp.equals("")){
118. return;
119. }
120. if(!exp.contains(" ")){
121. return;
122. }
123. if(clear_flag){
124. false;
125. return ;
126. }
127. true;
128. double result = 0;
129. 0, exp.indexOf(" "));
130. " ") + 1, exp.indexOf(" ") + 2);
131. " ") + 3);
132. if (!s1.equals("") && !s2.equals("")) {
133. double d1 = Double.parseDouble(s1);
134. double d2 = Double.parseDouble(s2);
135.
136. if (op.equals("+")) {
137. result = d1 + d2;
138. else if (op.equals("-")) {
139. result = d1 - d2;
140. else if (op.equals("*")) {
141. result = d1 * d2;
142. else if (op.equals("/")) {
143. if (d2 == 0) {
144. 0;
145. else {
146. result = d1 / d2;
147. }
148. }
149. if (!s1.contains(".") && !s2.contains(".") && !op.equals("/")) {
150. int r = (int) result;
151. "");
152. else {
153. "");
154. }
155. }
156.
157. else if(!s1.equals("")&&s2.equals("")){
158. et_input.setText(exp);
159. }
160. else if(s1.equals("")&&!s2.equals("")){
161. double d2=Double.parseDouble(s2);
162. if(op.equals("+")){
163. 0+d2;
164. else if(op.equals("-")){
165. 0-d2;
166. else if(op.equals("*")){
167. 0;
168. else if(op.equals("/")){
169. 0;
170. }
171. if(!s2.contains(".")){
172. int r=(int) result;
173. " ");
174. else{
175. " ");
176. }
177. else{
178. "");
179. }
180.
181. }
182. }