实验目的:
自主完成一个简单APP的设计工作,综合应用已经学到的Android UI设计技巧,重点注意合理使用布局。
实验要求:
- 完成一个计算器的设计,可以以手机自带的计算器为参考。设计过程中,注意考虑界面的美观性,不同机型的适应性,以及功能的完备性。
- 注意结合Activity的生命周期,考虑不同情况下计算器的界面状态。
- 如有余力,可以考虑实现一个高精度科学计算型的计算器。
项目文件结构:
1 package com.example.flyuz.calculator; 2 3 import android.support.v7.app.AppCompatActivity; 4 import android.os.Bundle; 5 import android.view.View; 6 import android.widget.Button; 7 import android.widget.EditText; 8 import android.content.res.Configuration; 9 import java.util.ArrayList; 10 import java.util.LinkedList; 11 import java.util.List; 12 13 public class MainActivity 14 extends AppCompatActivity implements View.OnClickListener { 15 // 16 Button btn_1, btn_2, btn_3, btn_4, btn_5, btn_6, btn_7, btn_8, btn_9, btn_0, btn_point; 17 // 18 Button btn_plus, btn_minus, btn_mul, btn_div; 19 // 20 Button btn_clear, btn_del, btn_l, btn_r, btn_res; 21 // 22 EditText input; 23 24 StringBuffer res = new StringBuffer(); 25 26 String errorMsg = "表达式错误"; 27 28 private void initView() { 29 btn_0 = (Button) findViewById(R.id.btn_0); 30 btn_1 = (Button) findViewById(R.id.btn_1); 31 btn_2 = (Button) findViewById(R.id.btn_2); 32 btn_3 = (Button) findViewById(R.id.btn_3); 33 btn_4 = (Button) findViewById(R.id.btn_4); 34 btn_5 = (Button) findViewById(R.id.btn_5); 35 btn_6 = (Button) findViewById(R.id.btn_6); 36 btn_7 = (Button) findViewById(R.id.btn_7); 37 btn_8 = (Button) findViewById(R.id.btn_8); 38 btn_9 = (Button) findViewById(R.id.btn_9); 39 btn_l = (Button) findViewById(R.id.btn_l); 40 btn_r = (Button) findViewById(R.id.btn_r); 41 42 btn_point = (Button) findViewById(R.id.btn_point); 43 btn_div = (Button) findViewById(R.id.btn_div); 44 btn_mul = (Button) findViewById(R.id.btn_mul); 45 btn_minus = (Button) findViewById(R.id.btn_minus); 46 btn_plus = (Button) findViewById(R.id.btn_plus); 47 btn_clear = (Button) findViewById(R.id.btn_clear); 48 btn_del = (Button) findViewById(R.id.btn_del); 49 btn_res = (Button) findViewById(R.id.btn_res); 50 51 input = (EditText) findViewById(R.id.input); 52 53 btn_0.setOnClickListener(this); 54 btn_1.setOnClickListener(this); 55 btn_2.setOnClickListener(this); 56 btn_3.setOnClickListener(this); 57 btn_4.setOnClickListener(this); 58 btn_5.setOnClickListener(this); 59 btn_6.setOnClickListener(this); 60 btn_7.setOnClickListener(this); 61 btn_8.setOnClickListener(this); 62 btn_9.setOnClickListener(this); 63 btn_point.setOnClickListener(this); 64 65 btn_l.setOnClickListener(this); 66 btn_r.setOnClickListener(this); 67 btn_del.setOnClickListener(this); 68 btn_clear.setOnClickListener(this); 69 btn_plus.setOnClickListener(this); 70 btn_minus.setOnClickListener(this); 71 btn_mul.setOnClickListener(this); 72 btn_div.setOnClickListener(this); 73 btn_res.setOnClickListener(this); 74 } 75 76 @Override 77 protected void onCreate(Bundle savedInstanceState) { 78 super.onCreate(savedInstanceState); 79 setContentView(R.layout.activity_main); 80 initView(); 81 } 82 @Override 83 public void onClick(View v) { 84 85 switch (v.getId()) { 86 case R.id.btn_0: 87 res.append("0"); 88 input.setText(res); 89 break; 90 case R.id.btn_1: 91 res.append("1"); 92 input.setText(res); 93 break; 94 case R.id.btn_2: 95 res.append("2"); 96 input.setText(res); 97 break; 98 case R.id.btn_3: 99 res.append("3"); 100 input.setText(res); 101 break; 102 case R.id.btn_4: 103 res.append("4"); 104 input.setText(res); 105 break; 106 case R.id.btn_5: 107 res.append("5"); 108 input.setText(res); 109 break; 110 case R.id.btn_6: 111 res.append("6"); 112 input.setText(res); 113 break; 114 case R.id.btn_7: 115 res.append("7"); 116 input.setText(res); 117 break; 118 case R.id.btn_8: 119 res.append("8"); 120 input.setText(res); 121 break; 122 case R.id.btn_9: 123 res.append("9"); 124 input.setText(res); 125 break; 126 case R.id.btn_l: 127 res.append("("); 128 input.setText(res); 129 break; 130 case R.id.btn_r: 131 res.append(")"); 132 input.setText(res); 133 break; 134 case R.id.btn_point: 135 res.append("."); 136 input.setText(res); 137 break; 138 case R.id.btn_plus: 139 res.append("+"); 140 input.setText(res); 141 break; 142 case R.id.btn_minus: 143 res.append("-"); 144 input.setText(res); 145 break; 146 case R.id.btn_mul: 147 res.append("*"); 148 input.setText(res); 149 break; 150 case R.id.btn_div: 151 res.append("/"); 152 input.setText(res); 153 break; 154 case R.id.btn_del: 155 if (res.length() != 0) { 156 res.deleteCharAt(res.length() - 1); 157 input.setText(res); 158 } 159 break; 160 case R.id.btn_clear: 161 res.setLength(0); 162 input.setText(res); 163 break; 164 case R.id.btn_res: 165 res.append("="); 166 String in = new String(res); 167 String out = prepareParam(in); 168 res.setLength(0); 169 res.append(out); 170 input.setText(out); 171 break; 172 } 173 } 174 175 public String prepareParam(String str) { 176 if (str == null || str.length() == 0 || str.length() > 20) { 177 return errorMsg; 178 } 179 if (str.charAt(0) == '-') { 180 str = "0" + str; 181 } 182 if (!tools.checkFormat(str)) { 183 return errorMsg; 184 } 185 // 处理表达式,改为标准表达式 186 str = tools.change2StandardFormat(str); 187 // 拆分字符和数字 188 String[] nums = str.split("[^.0-9]"); 189 List<Double> numLst = new ArrayList(); 190 for (int i = 0; i < nums.length; i++) { 191 if (!"".equals(nums[i])) { 192 numLst.add(Double.parseDouble(nums[i])); 193 } 194 } 195 String symStr = str.replaceAll("[.0-9]", ""); 196 return doCalculate(symStr, numLst); 197 } 198 199 public String doCalculate(String symStr, List<Double> numLst) { 200 String errorMsg = "表达式错误"; 201 LinkedList<Character> symStack = new LinkedList<>(); // 符号栈 202 LinkedList<Double> numStack = new LinkedList<>(); // 数字栈 203 int i = 0; // numLst的标志位 204 int j = 0; // symStr的标志位 205 char sym; // 符号 206 double num1, num2; // 符号前后两个数 207 while (symStack.isEmpty() || !(symStack.getLast() == '=' && symStr.charAt(j) == '=')) { 208 if (symStack.isEmpty()) { 209 symStack.add('='); 210 numStack.add(numLst.get(i++)); 211 } 212 if (tools.symLvMap.get(symStr.charAt(j)) > tools.symLvMap.get(symStack.getLast())) { // 比较符号优先级,若当前符号优先级大于前一个则压栈 213 if (symStr.charAt(j) == '(') { 214 symStack.add(symStr.charAt(j++)); 215 continue; 216 } 217 numStack.add(numLst.get(i++)); 218 symStack.add(symStr.charAt(j++)); 219 } else { // 当前符号优先级小于等于前一个 符号的优先级 220 if (symStr.charAt(j) == ')' && symStack.getLast() == '(') { // 若()之间没有符号,则“(”出栈 221 j++; 222 symStack.removeLast(); 223 continue; 224 } 225 if (symStack.getLast() == '(') { // “(”直接压栈 226 numStack.add(numLst.get(i++)); 227 symStack.add(symStr.charAt(j++)); 228 continue; 229 } 230 num2 = numStack.removeLast(); 231 num1 = numStack.removeLast(); 232 sym = symStack.removeLast(); 233 switch (sym) { 234 case '+': 235 numStack.add(tools.plus(num1, num2)); 236 break; 237 case '-': 238 numStack.add(tools.reduce(num1, num2)); 239 break; 240 case '*': 241 numStack.add(tools.multiply(num1, num2)); 242 break; 243 case '/': 244 if (num2 == 0) { // 除数为0 245 return errorMsg; 246 } 247 numStack.add(tools.divide(num1, num2)); 248 break; 249 } 250 } 251 } 252 return String.valueOf(numStack.removeLast()); 253 } 254 }