一个计算器Android程序的源码部分分为主干和细节两部分。
一、主干
1. 主干的构成
- 计算器的布局
- 事件(即计算器上的按钮、文本框)监听
- 实现计算
2. 详细解释
假设我们的项目名为Calculator,而布局名称(Layout Name)为默认的activity_main 。即设置如下图所示:
在这种前提下,有:
- 设置计算器布局的文件:Calculator/app/src/main/res/layout/activity_main.xml
- 事件监听和计算实现在同一个文件里:Calculator/app/src/main/java/下的一个子目录里的MainActivity.java
即如下图所示:
3. 主干代码部分
- 计算器布局代码(写在activity_main.xml文件里):
1 <?xml version="1.0" encoding="utf-8"?> 2 <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="fill_parent" 4 android:layout_height="wrap_content" 5 > 6 <LinearLayout 7 android:layout_width="fill_parent" 8 android:layout_height="fill_parent" 9 android:orientation="vertical" > 10 <EditText 11 android:id="@+id/input" 12 android:layout_width="fill_parent" 13 android:layout_height="wrap_content" 14 android:layout_gravity="center" 15 android:editable="false" 16 android:hint="@string/shuru" /> 17 18 <EditText 19 android:id="@+id/output" 20 android:layout_width="fill_parent" 21 android:layout_height="wrap_content" 22 android:layout_gravity="center" 23 android:editable="true" 24 android:gravity="right" 25 android:hint="@string/shuchu" /> 26 27 <RelativeLayout 28 android:layout_width="fill_parent" 29 android:layout_height="wrap_content" > 30 31 <Button 32 android:id="@+id/seven" 33 android:layout_width="80dp" 34 android:layout_height="70dp" 35 android:layout_alignParentLeft="true" 36 android:text="@string/seven" 37 android:textSize="40sp" /> 38 39 <Button 40 android:id="@+id/eight" 41 android:layout_width="80dp" 42 android:layout_height="70dp" 43 android:layout_toRightOf="@id/seven" 44 android:text="@string/eight" 45 android:textSize="40sp" /> 46 47 <Button 48 android:id="@+id/nine" 49 android:layout_width="80dp" 50 android:layout_height="70dp" 51 android:layout_toRightOf="@id/eight" 52 android:text="@string/nine" 53 android:textSize="40sp" /> 54 55 <Button 56 android:id="@+id/add" 57 android:layout_width="80dp" 58 android:layout_height="70dp" 59 android:layout_alignParentRight="true" 60 android:layout_toRightOf="@id/nine" 61 android:text="@string/add" 62 android:textSize="40sp" /> 63 64 <Button 65 android:id="@+id/four" 66 android:layout_width="80dp" 67 android:layout_height="70dp" 68 android:layout_alignParentLeft="true" 69 android:layout_below="@id/seven" 70 android:text="@string/four" 71 android:textSize="40sp" /> 72 73 <Button 74 android:id="@+id/five" 75 android:layout_width="80dp" 76 android:layout_height="70dp" 77 android:layout_below="@id/eight" 78 android:layout_toRightOf="@id/four" 79 android:text="@string/five" 80 android:textSize="40sp" /> 81 82 <Button 83 android:id="@+id/six" 84 android:layout_width="80dp" 85 android:layout_height="70dp" 86 android:layout_below="@id/nine" 87 android:layout_toRightOf="@id/five" 88 android:text="@string/six" 89 android:textSize="40sp" /> 90 91 <Button 92 android:id="@+id/subtract" 93 android:layout_width="80dp" 94 android:layout_height="70dp" 95 android:layout_alignParentRight="true" 96 android:layout_below="@id/add" 97 android:layout_toRightOf="@id/six" 98 android:text="@string/subtract" 99 android:textSize="40sp" /> 100 101 <Button 102 android:id="@+id/one" 103 android:layout_width="80dp" 104 android:layout_height="70dp" 105 android:layout_alignParentLeft="true" 106 android:layout_below="@id/four" 107 android:text="@string/one" 108 android:textSize="40sp" /> 109 110 <Button 111 android:id="@+id/two" 112 android:layout_width="80dp" 113 android:layout_height="70dp" 114 android:layout_below="@id/five" 115 android:layout_toRightOf="@id/one" 116 android:text="@string/two" 117 android:textSize="40sp" /> 118 119 <Button 120 android:id="@+id/three" 121 android:layout_width="80dp" 122 android:layout_height="70dp" 123 android:layout_below="@id/six" 124 android:layout_toRightOf="@id/two" 125 android:text="@string/three" 126 android:textSize="40sp" /> 127 128 <Button 129 android:id="@+id/multiply" 130 android:layout_width="80dp" 131 android:layout_height="70dp" 132 android:layout_alignParentRight="true" 133 android:layout_below="@id/subtract" 134 android:layout_toRightOf="@id/three" 135 android:text="@string/multiply" 136 android:textSize="40sp" /> 137 138 <Button 139 android:id="@+id/zero" 140 android:layout_width="80dp" 141 android:layout_height="70dp" 142 android:layout_alignParentLeft="true" 143 android:layout_below="@id/one" 144 android:text="@string/zero" 145 android:textSize="40sp" /> 146 147 <Button 148 android:id="@+id/clear" 149 android:layout_width="80dp" 150 android:layout_height="70dp" 151 android:layout_below="@id/two" 152 android:layout_toRightOf="@id/zero" 153 android:text="@string/clear" 154 android:textSize="40sp" /> 155 156 <Button 157 android:id="@+id/result" 158 android:layout_width="80dp" 159 android:layout_height="70dp" 160 android:layout_below="@id/three" 161 android:layout_toRightOf="@id/clear" 162 android:text="@string/result" 163 android:textSize="40sp" /> 164 165 <Button 166 android:id="@+id/divide" 167 android:layout_width="80dp" 168 android:layout_height="70dp" 169 android:layout_alignParentRight="true" 170 android:layout_below="@id/multiply" 171 android:layout_toRightOf="@id/result" 172 android:text="@string/divide" 173 android:textSize="40sp" /> 174 175 <Button 176 android:id="@+id/dot" 177 android:layout_width="80dp" 178 android:layout_height="70dp" 179 android:layout_alignParentLeft="true" 180 android:layout_below="@id/zero" 181 android:text="@string/dot" 182 android:textSize="40sp" /> 183 <Button 184 android:id="@+id/writeButton" 185 android:layout_width="wrap_content" 186 android:layout_height="wrap_content" 187 android:layout_alignParentLeft="true" 188 android:layout_below="@id/dot" 189 android:text="@string/write" 190 android:textSize="40sp" /> 191 <Button 192 android:id="@+id/readButton" 193 android:layout_width="wrap_content" 194 android:layout_height="wrap_content" 195 android:layout_alignParentRight="true" 196 android:layout_below="@id/dot" 197 android:text="@string/read" 198 android:textSize="40sp" /> 199 200 <CheckBox 201 android:id="@+id/appendBox" 202 android:text="@string/appendBox" 203 android:layout_width="wrap_content" 204 android:layout_height="wrap_content" 205 android:layout_alignParentBottom="true" 206 android:layout_toLeftOf="@+id/divide" 207 android:layout_toStartOf="@+id/divide" 208 android:layout_marginBottom="12dp" 209 /> 210 211 </RelativeLayout> 212 213 <EditText 214 215 android:layout_width="match_parent" 216 android:layout_height="wrap_content" 217 android:id="@+id/textView" /> 218 219 <EditText 220 221 android:layout_width="match_parent" 222 android:layout_height="wrap_content" 223 android:id="@+id/displayView" /> 224 225 <EditText 226 android:id="@+id/errorzero" 227 android:layout_width="fill_parent" 228 android:layout_height="wrap_content" 229 android:layout_gravity="center" 230 android:editable="false" 231 android:gravity="center" 232 /> 233 <EditText 234 android:id="@+id/resultText" 235 android:layout_width="fill_parent" 236 android:layout_height="wrap_content" 237 android:layout_gravity="center" 238 android:editable="false" 239 android:gravity="left" 240 android:text="@string/resultText" 241 /> 242 </LinearLayout> 243 </ScrollView>
- 事件监听和实现计算代码(写在MainActivity.java文件里)
1 package com.example.lenovo.calculator; 2 3 4 5 import android.app.Activity; 6 import android.content.Context; 7 import android.os.Bundle; 8 import android.view.View; 9 import android.view.View.OnClickListener; 10 import android.widget.Button; 11 import android.widget.CheckBox; 12 import android.widget.EditText; 13 14 import java.io.FileInputStream; 15 import java.io.FileNotFoundException; 16 import java.io.FileOutputStream; 17 import java.io.IOException; 18 19 public class MainActivity extends Activity { 20 /** 21 * Called when the activity is first created. 22 */ 23 private EditText output = null; 24 private EditText input = null; 25 private Button btn0 = null; 26 private Button btn1 = null; 27 private Button btn2 = null; 28 private Button btn3 = null; 29 private Button btn4 = null; 30 private Button btn5 = null; 31 private Button btn6 = null; 32 private Button btn7 = null; 33 private Button btn8 = null; 34 private Button btn9 = null; 35 private Button btnadd = null; 36 private Button btnsubtract = null; 37 private Button btnmultiply = null; 38 private Button btndivide = null; 39 private Button btnclear = null; 40 private Button btnresult = null; 41 private Button btndot = null; 42 43 private EditText errorzero = null; 44 45 private EditText resultText = null; 46 private Button writeButton = null; 47 private Button readButton = null; 48 private CheckBox appendBox = null; 49 private EditText textView = null; 50 private EditText displayView = null; 51 public String FILE_NAME = "fileDemo.txt"; 52 53 54 private String str = "";//保存数字 55 private String strold = "";//原数字 56 private char act = ' ';//记录“加减乘除等于”符号 57 private int count = 0;//判断要计算的次数,如果超过一个符号,先算出来一部分 58 private Float result = null;//计算的输出结果 59 private Boolean errBoolean = false;//有错误的时候为true,无错为false 60 private Boolean flagBoolean = false;//一个标志,如果为true,可以响应运算消息,如果为false,不响应运算消息,只有前面是数字才可以响应运算消息 61 private Boolean flagDot = false; //小数点标志位 62 63 64 65 @Override 66 public void onCreate(Bundle savedInstanceState) { 67 super.onCreate(savedInstanceState); 68 setContentView(R.layout.activity_main); 69 70 output = (EditText) findViewById(R.id.output); 71 input = (EditText) findViewById(R.id.input); 72 73 errorzero = (EditText) findViewById(R.id.errorzero); 74 resultText = (EditText) findViewById(R.id.resultText); 75 writeButton = (Button) findViewById(R.id.writeButton); 76 readButton = (Button) findViewById(R.id.readButton); 77 textView = (EditText) findViewById(R.id.textView); 78 displayView = (EditText) findViewById(R.id.displayView); 79 appendBox = (CheckBox) findViewById(R.id.appendBox); 80 81 btn0 = (Button) findViewById(R.id.zero); 82 btn1 = (Button) findViewById(R.id.one); 83 btn2 = (Button) findViewById(R.id.two); 84 btn3 = (Button) findViewById(R.id.three); 85 btn4 = (Button) findViewById(R.id.four); 86 btn5 = (Button) findViewById(R.id.five); 87 btn6 = (Button) findViewById(R.id.six); 88 btn7 = (Button) findViewById(R.id.seven); 89 btn8 = (Button) findViewById(R.id.eight); 90 btn9 = (Button) findViewById(R.id.nine); 91 btnadd = (Button) findViewById(R.id.add); 92 btnsubtract = (Button) findViewById(R.id.subtract); 93 btnmultiply = (Button) findViewById(R.id.multiply); 94 btndivide = (Button) findViewById(R.id.divide); 95 btnclear = (Button) findViewById(R.id.clear); 96 btnresult = (Button) findViewById(R.id.result); 97 btndot = (Button) findViewById(R.id.dot); 98 //设置按钮侦听事件 99 btn0.setOnClickListener(listener); 100 btn1.setOnClickListener(listener); 101 btn2.setOnClickListener(listener); 102 btn3.setOnClickListener(listener); 103 btn4.setOnClickListener(listener); 104 btn5.setOnClickListener(listener); 105 btn6.setOnClickListener(listener); 106 btn7.setOnClickListener(listener); 107 btn8.setOnClickListener(listener); 108 btn9.setOnClickListener(listener); 109 //执行运算 110 btnadd.setOnClickListener(listener); 111 btnsubtract.setOnClickListener(listener); 112 btnmultiply.setOnClickListener(listener); 113 btndivide.setOnClickListener(listener); 114 btnclear.setOnClickListener(listener); 115 btnresult.setOnClickListener(listener); 116 117 btndot.setOnClickListener(listener); 118 119 writeButton.setOnClickListener(writelistener); 120 readButton.setOnClickListener(readlistener); 121 122 123 // ATTENTION: This was auto-generated to implement the App Indexing API. 124 // See https://g.co/AppIndexing/AndroidStudio for more information. 125 } 126 127 128 private OnClickListener listener = new OnClickListener() { 129 130 public void onClick(View v) { 131 // TODO Auto-generated method stub 132 switch (v.getId()) { 133 //输入数字 134 case R.id.zero: 135 num(0); 136 break; 137 case R.id.one: 138 num(1); 139 break; 140 case R.id.two: 141 num(2); 142 break; 143 case R.id.three: 144 num(3); 145 break; 146 case R.id.four: 147 num(4); 148 break; 149 case R.id.five: 150 num(5); 151 break; 152 case R.id.six: 153 num(6); 154 break; 155 case R.id.seven: 156 num(7); 157 break; 158 case R.id.eight: 159 num(8); 160 break; 161 case R.id.nine: 162 num(9); 163 break; 164 165 case R.id.dot: 166 dot(); 167 break; 168 //执行运算 169 case R.id.add: 170 add(); 171 break; 172 case R.id.subtract: 173 sub(); 174 break; 175 case R.id.multiply: 176 multiply(); 177 break; 178 case R.id.divide: 179 divide(); 180 break; 181 case R.id.clear: 182 clear(); 183 break; 184 //计算结果 185 case R.id.result: 186 result(); 187 if (!errBoolean && flagBoolean) { 188 output.setText(String.valueOf(result)); 189 } 190 resultText.setText(strold + act + str + "=" + result+" "); 191 break; 192 193 default: 194 break; 195 196 } 197 input.setText(strold + act + str); 198 output.setText(String.valueOf(result)); 199 200 201 } 202 }; 203 204 private OnClickListener writelistener = new OnClickListener() { 205 @Override 206 public void onClick(View view) { 207 //textView.setText(""); 208 209 FileOutputStream fos = null; 210 try { 211 if (appendBox.isChecked()) { 212 fos = openFileOutput(FILE_NAME, Context.MODE_APPEND); 213 } else { 214 fos = openFileOutput(FILE_NAME, Context.MODE_PRIVATE); 215 } 216 String text = resultText.getText().toString(); 217 fos.write(text.getBytes()); 218 textView.setText("文件写入成功,写入长度:" + text.length()); 219 //resultText.setText(""); 220 221 } catch (FileNotFoundException e) { 222 e.printStackTrace(); 223 } catch (IOException e) { 224 e.printStackTrace(); 225 } 226 finally { 227 if (fos != null) 228 try { 229 fos.flush(); 230 fos.close(); 231 } catch (IOException e) { 232 e.printStackTrace(); 233 } 234 } 235 } 236 }; 237 private OnClickListener readlistener = new OnClickListener() { 238 @Override 239 public void onClick(View view) { 240 241 displayView.setText(""); 242 FileInputStream fis = null; 243 try { 244 fis = openFileInput(FILE_NAME); 245 if (fis.available() == 0) { 246 return; 247 } 248 byte[] readBytes = new byte[fis.available()]; 249 while (fis.read(readBytes) != -1) { 250 251 } 252 String text = new String(readBytes); 253 displayView.setText(text); 254 textView.setText("文件读取成功,写入长度:" + text.length()); 255 256 } catch (FileNotFoundException e) { 257 e.printStackTrace(); 258 } catch (IOException e) { 259 e.printStackTrace(); 260 } 261 262 } 263 }; 264 265 private void dot() { 266 // TODO Auto-generated method stub 267 268 if (!flagDot) { 269 str = str + "."; 270 flagBoolean = false; 271 flagDot = true; 272 } 273 } 274 275 private void clear() { 276 // TODO Auto-generated method stub 277 str = strold = ""; 278 count = 0; 279 act = ' '; 280 result = null; 281 flagBoolean = false; 282 flagDot = false; 283 input.setText(strold + act + str); 284 output.setText(""); 285 errorzero.setText(""); 286 displayView.setText(""); 287 textView.setText(""); 288 resultText.setText(""); 289 } 290 291 private void divide() { 292 // TODO Auto-generated method stub 293 if (flagBoolean) { 294 check(); 295 act = '/'; 296 flagBoolean = false; 297 } 298 } 299 300 private void multiply() { 301 // TODO Auto-generated method stub 302 if (flagBoolean) { 303 check(); 304 act = '*'; 305 flagBoolean = false; 306 } 307 } 308 309 private void sub() { 310 // TODO Auto-generated method stub 311 if (flagBoolean) { 312 check(); 313 act = '-'; 314 flagBoolean = false; 315 } 316 } 317 318 private void add() { 319 // TODO Auto-generated method stub 320 if (flagBoolean) { 321 check(); 322 act = '+'; 323 flagBoolean = false; 324 } 325 } 326 327 private void check() { 328 // TODO Auto-generated method stub 329 if (count >= 1) { 330 result(); 331 str = String.valueOf(result); 332 } 333 strold = str; 334 str = ""; 335 count++; 336 flagDot = false; 337 errorzero.setText(""); 338 } 339 340 //计算输出结果 341 private void result() { 342 // TODO Auto-generated method stub 343 if (flagBoolean) { 344 Float a, b; 345 346 a = Float.parseFloat(strold); 347 b = Float.parseFloat(str); 348 349 if (b == 0 && act == '/') { 350 clear(); 351 errorzero.setText("除数不能为零!"); 352 //output.setText("除数不能为零!"); 353 354 355 //errBoolean=true; 356 } 357 358 359 if (!errBoolean) { 360 switch (act) { 361 case '+': 362 result = a + b; 363 break; 364 case '-': 365 result = a - b; 366 break; 367 case '*': 368 result = a * b; 369 break; 370 case '/': 371 result = a / b; 372 break; 373 374 default: 375 break; 376 } 377 } 378 379 380 } 381 } 382 383 private void num(int i) { 384 // TODO Auto-generated method stub 385 str = str + String.valueOf(i); 386 flagBoolean = true; 387 errorzero.setText(""); 388 } 389 390 }
二、细节
仅仅将主干部分代码copy下来并不能运行程序,因为主干代码调用了一些文件的代码,这些文件就是我们所说的细节。
1. 字符串资源
- 文件位置:Calculator/app/src/main/res/values/strings.xml
- 代码部分:
1 <resources> 2 <string name="app_name">Calculator</string> 3 <string name="action_settings">Settings</string> 4 <string name="zero">0</string> 5 <string name="one">1</string> 6 <string name="two">2</string> 7 <string name="three">3</string> 8 <string name="four">4</string> 9 <string name="five">5</string> 10 <string name="six">6</string> 11 <string name="seven">7</string> 12 <string name="eight">8</string> 13 <string name="nine">9</string> 14 <string name="add">+</string> 15 <string name="subtract">-</string> 16 <string name="multiply">*</string> 17 <string name="divide">/</string> 18 <string name="clear">CE</string> 19 <string name="result">=</string> 20 <string name="shuru">请按数字键盘输入数字</string> 21 <string name="shuchu">计算器输出结果</string> 22 <string name="dot">.</string> 23 <string name="write">写入</string> 24 <string name="read">读取</string> 25 <string name="resultText">计算式</string> 26 <string name="appendBox">追加模式</string> 27 28 </resources>
2. 其他可能要改的文件
- Calculator/app/src/main/res/drawable:设置相关的背景颜色、按钮特效
- Calculator/app/src/main/AndroidManifest.xml:设置这个项目的整体配置
三、备注
- 本文提供的简易计算器仅需要修改前三个文件(布局文件、监听实现文件、字符串资源文件)
- 纯复制粘贴是一定会报错的,留意一点将有些地方改动一下