功能简单,实现并不难,对于初学者可以总和了解初级控件的基本使用。
用到的知识点如下:
- 线性布局 LinearLayout:整体界面是从上往下的,因此需要垂直方向的linearlayout;下面每行四个按钮,需要水平的linearlayout。
- 滚动视图 ScrollView :虽然界面不宽也不高,以防万一,有可能会遇到屏幕特别小的手机,因此用一个垂直方向的scrollview。
- 文本视图 TextView :上面标题就是一个textview,结果显示也是textview,但是更高级。能够从下往上滚动,前面的聊天室效果里用到过。
- 按钮 Button :下面的数字、运算符都是按钮。
- 图像视图 ImageView :未用到。
- 图像按钮 ImageButton :由于开根号运算符(√)虽然可以打出来,但是有点不一样,因此需要用到一个图像,就用到了图像按钮。
- 状态列表图形 :都有按下和弹起两种状态,因此订制了按钮的自定义样式。
- 形状图形 :运算结果用到的textview是一个圆角的矩形,所以定义了shape文件,把它作为文本视图的背景。
- 九宫格图片 :最下面的“0”按钮是有点大,因此需要两倍那么大的图片,如果使用普通的图片则会拉宽,效果很不好。因此就用到了。
style
12 3 4 10 19 20
xml
17 8 177 178 179 180 18111 12 16 17 155 15624 25 30 31 42 4341 47 48 125 12652 53 57 58 62 63 67 68 72 73 7478 79 83 84 88 89 93 94 98 99 100104 105 109 110 114 115 119 120 124 130 131 135 136 140 141 145 146 154 160 161 166 167 171 172 176
nineselec0tor
1 23 - 4
- 5
putong
1 23 0- 4
- 5
shape_oval
1 24 5 6 7 10 11
rect
1 23 4 5 6 9 10 15 16
white_stroke
1 23 4 5 6 9 10 15 16
main
1 package com.example.alimjan.hello_world; 2 3 import android.app.Activity; 4 import android.content.Context; 5 import android.content.Intent; 6 import android.os.Bundle; 7 import android.support.annotation.Nullable; 8 9 /** 10 * Created by alimjan on 7/1/2017. 11 */ 12 13 import android.support.v7.app.AppCompatActivity; 14 import android.text.method.ScrollingMovementMethod; 15 import android.util.Log; 16 import android.view.View; 17 import android.widget.TextView; 18 import android.widget.Toast; 19 20 import com.example.alimjan.hello_world.Arith; 21 22 23 public class class__2_5 extends AppCompatActivity implements View.OnClickListener { 24 25 private final static String TAG = "CalculatorActivity"; 26 private TextView tv_result; 27 28 @Override 29 protected void onCreate(Bundle savedInstanceState) { 30 super.onCreate(savedInstanceState); 31 setContentView(R.layout.code_2_5); 32 tv_result = (TextView) findViewById(R.id.tv_result); 33 tv_result.setMovementMethod(new ScrollingMovementMethod()); 34 35 findViewById(R.id.btn_cancel).setOnClickListener(this); 36 findViewById(R.id.btn_divide).setOnClickListener(this); 37 findViewById(R.id.btn_multiply).setOnClickListener(this); 38 findViewById(R.id.btn_clear).setOnClickListener(this); 39 findViewById(R.id.btn_seven).setOnClickListener(this); 40 findViewById(R.id.btn_eight).setOnClickListener(this); 41 findViewById(R.id.btn_nine).setOnClickListener(this); 42 findViewById(R.id.btn_plus).setOnClickListener(this); 43 findViewById(R.id.btn_four).setOnClickListener(this); 44 findViewById(R.id.btn_five).setOnClickListener(this); 45 findViewById(R.id.btn_six).setOnClickListener(this); 46 findViewById(R.id.btn_minus).setOnClickListener(this); 47 findViewById(R.id.btn_one).setOnClickListener(this); 48 findViewById(R.id.btn_two).setOnClickListener(this); 49 findViewById(R.id.btn_three).setOnClickListener(this); 50 findViewById(R.id.btn_zero).setOnClickListener(this); 51 findViewById(R.id.btn_dot).setOnClickListener(this); 52 findViewById(R.id.btn_equal).setOnClickListener(this); 53 findViewById(R.id.ib_sqrt).setOnClickListener(this); 54 } 55 56 @Override 57 public void onClick(View v) { 58 int resid = v.getId(); 59 String inputText; 60 if (resid == R.id.ib_sqrt) { 61 inputText = "√"; 62 } else { 63 inputText = ((TextView) v).getText().toString(); 64 } 65 Log.d(TAG, "resid="+resid+",inputText="+inputText); 66 if (resid == R.id.btn_clear) { 67 clear(""); 68 } else if (resid == R.id.btn_cancel) { 69 if (operator.equals("") == true) { 70 if (firstNum.length() == 1) { 71 firstNum = "0"; 72 } else if (firstNum.length() > 0) { 73 firstNum = firstNum.substring(0, firstNum.length() - 1); 74 } else { 75 Toast.makeText(this, "没有可取消的数字了", Toast.LENGTH_SHORT).show(); 76 return; 77 } 78 showText = firstNum; 79 tv_result.setText(showText); 80 } else { 81 if (nextNum.length() == 1) { 82 nextNum = ""; 83 } else if (nextNum.length() > 0) { 84 nextNum = nextNum.substring(0, nextNum.length() - 1); 85 } else { 86 Toast.makeText(this, "没有可取消的数字了", Toast.LENGTH_SHORT).show(); 87 return; 88 } 89 showText = showText.substring(0, showText.length() - 1); 90 tv_result.setText(showText); 91 } 92 } else if (resid == R.id.btn_equal) { 93 if (operator.length() == 0 || operator.equals("=") == true) { 94 Toast.makeText(this, "请输入运算符", Toast.LENGTH_SHORT).show(); 95 return; 96 } else if (nextNum.length() <= 0) { 97 Toast.makeText(this, "请输入数字", Toast.LENGTH_SHORT).show(); 98 return; 99 }100 if (caculate() == true) {101 operator = inputText;102 showText = showText + "=" + result;103 tv_result.setText(showText);104 } else {105 return;106 }107 } else if (resid == R.id.btn_plus || resid == R.id.btn_minus108 || resid == R.id.btn_multiply || resid == R.id.btn_divide ) {109 if (firstNum.length() <= 0) {110 Toast.makeText(this, "请输入数字", Toast.LENGTH_SHORT).show();111 return;112 }113 if (operator.length() == 0 || operator.equals("=") == true114 || operator.equals("√") == true) {115 operator = inputText;// 操作符116 showText = showText + operator;117 tv_result.setText(showText);118 } else {119 Toast.makeText(this, "请输入数字", Toast.LENGTH_SHORT).show();120 return;121 }122 } else if (resid == R.id.ib_sqrt) {123 if (firstNum.length() <= 0) {124 Toast.makeText(this, "请输入数字", Toast.LENGTH_SHORT).show();125 return;126 }127 if (Double.parseDouble(firstNum) < 0) {128 Toast.makeText(this, "开根号的数值不能小于0", Toast.LENGTH_SHORT).show();129 return;130 }131 result = String.valueOf(Math.sqrt(Double.parseDouble(firstNum)));132 firstNum = result;133 nextNum = "";134 operator = inputText;135 showText = showText + "√=" + result;136 tv_result.setText(showText);137 Log.d(TAG, "result="+result+",firstNum="+firstNum+",operator="+operator);138 } else {139 if (operator.equals("=") == true) {140 operator = "";141 firstNum = "";142 showText = "";143 }144 if (resid == R.id.btn_dot) {145 inputText = ".";146 }147 if (operator.equals("") == true) {148 firstNum = firstNum + inputText;149 } else {150 nextNum = nextNum + inputText;151 }152 showText = showText + inputText;153 tv_result.setText(showText);154 }155 return;156 }157 158 private String operator = ""; // 操作符159 private String firstNum = ""; // 前一个操作数160 private String nextNum = ""; // 后一个操作数161 private String result = ""; // 当前的计算结果162 private String showText = ""; // 显示的文本内容163 164 // 开始加减乘除四则运算165 private boolean caculate() {166 if (operator.equals("+") == true) {167 result = String.valueOf(Arith.add(firstNum, nextNum));168 } else if (operator.equals("-") == true) {169 result = String.valueOf(Arith.sub(firstNum, nextNum));170 } else if (operator.equals("×") == true) {171 result = String.valueOf(Arith.mul(firstNum, nextNum));172 } else if (operator.equals("÷") == true) {173 if ("0".equals(nextNum)) {174 Toast.makeText(this, "被除数不能为零", Toast.LENGTH_SHORT).show();175 return false;176 } else {177 result = String.valueOf(Arith.div(firstNum, nextNum));178 }179 }180 firstNum = result;181 nextNum = "";182 return true;183 }184 185 // 清空并初始化186 private void clear(String text) {187 showText = text;188 tv_result.setText(showText);189 operator = "";190 firstNum = "";191 nextNum = "";192 result = "";193 }194 195 public static void startHome(Context mContext) {196 Intent intent = new Intent(mContext, class__2_5.class);197 mContext.startActivity(intent);198 }199 200 }
Arith
1 package com.example.alimjan.hello_world; 2 3 import java.math.BigDecimal; 4 5 public class Arith { 6 // 默认除法运算精度 7 private static final int DEF_DIV_SCALE = 10; 8 9 // 这个类不能实例化 10 private Arith() { 11 ; 12 } 13 14 /** 15 * 提供精确的加法运算。 16 * 17 * @param v1 18 * 被加数 19 * @param v2 20 * 加数 21 * @return 两个参数的和 22 */ 23 public static String add(double v1, double v2) { 24 BigDecimal b1 = new BigDecimal(Double.toString(v1)); 25 BigDecimal b2 = new BigDecimal(Double.toString(v2)); 26 return String.valueOf(b1.add(b2)); 27 } 28 29 /** 30 * 提供精确的加法运算。 31 * 32 * @param v1 33 * 被加数 34 * @param v2 35 * 加数 36 * @return 两个参数的和 37 */ 38 public static String add(String v1, String v2) { 39 BigDecimal b1 = new BigDecimal(v1); 40 BigDecimal b2 = new BigDecimal(v2); 41 return String.valueOf(b1.add(b2)); 42 } 43 44 /** 45 * 提供精确的减法运算。 46 * 47 * @param v1 48 * 被减数 49 * @param v2 50 * 减数 51 * @return 两个参数的差 52 */ 53 public static String sub(double v1, double v2) { 54 BigDecimal b1 = new BigDecimal(Double.toString(v1)); 55 BigDecimal b2 = new BigDecimal(Double.toString(v2)); 56 return String.valueOf(b1.subtract(b2)); 57 } 58 59 /** 60 * 提供精确的减法运算。 61 * 62 * @param v1 63 * 被减数 64 * @param v2 65 * 减数 66 * @return 两个参数的差 67 */ 68 public static String sub(String v1, String v2) { 69 BigDecimal b1 = new BigDecimal(v1); 70 BigDecimal b2 = new BigDecimal(v2); 71 return String.valueOf(b1.subtract(b2)); 72 } 73 74 /** 75 * 提供精确的乘法运算。 76 * 77 * @param v1 78 * 被乘数 79 * @param v2 80 * 乘数 81 * @return 两个参数的积 82 */ 83 public static String mul(double v1, double v2) { 84 BigDecimal b1 = new BigDecimal(Double.toString(v1)); 85 BigDecimal b2 = new BigDecimal(Double.toString(v2)); 86 return String.valueOf(b1.multiply(b2)); 87 } 88 89 /** 90 * 提供精确的乘法运算。 91 * 92 * @param v1 93 * 被乘数 94 * @param v2 95 * 乘数 96 * @return 两个参数的积 97 */ 98 public static String mul(String v1, String v2) { 99 BigDecimal b1 = new BigDecimal(v1);100 BigDecimal b2 = new BigDecimal(v2);101 return String.valueOf(b1.multiply(b2));102 }103 104 /**105 * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入。106 * 107 * @param v1108 * 被除数109 * @param v2110 * 除数111 * @return 两个参数的商112 */113 public static String div(double v1, double v2) {114 return div(v1, v2, DEF_DIV_SCALE);115 }116 117 /**118 * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入。119 * 120 * @param v1121 * 被除数122 * @param v2123 * 除数124 * @return 两个参数的商125 */126 public static String div(String v1, String v2) {127 return div(v1, v2, DEF_DIV_SCALE);128 }129 130 /**131 * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。132 * 133 * @param v1134 * 被除数135 * @param v2136 * 除数137 * @param scale138 * 表示表示需要精确到小数点以后几位。139 * @return 两个参数的商140 */141 public static String div(double v1, double v2, int scale) {142 if (scale < 0) {143 throw new IllegalArgumentException(144 "The scale must be a positive integer or zero");145 }146 BigDecimal b1 = new BigDecimal(Double.toString(v1));147 BigDecimal b2 = new BigDecimal(Double.toString(v2));148 return String.valueOf(b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP));149 }150 151 /**152 * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。153 * 154 * @param v1155 * 被除数156 * @param v2157 * 除数158 * @param scale159 * 表示表示需要精确到小数点以后几位。160 * @return 两个参数的商161 */162 public static String div(String v1, String v2, int scale) {163 if (scale < 0) {164 throw new IllegalArgumentException(165 "The scale must be a positive integer or zero");166 }167 BigDecimal b1 = new BigDecimal(v1);168 BigDecimal b2 = new BigDecimal(v2);169 170 BigDecimal result = null;171 try {172 result = b1.divide(b2);173 } catch (Exception e) {174 result = b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP);175 }176 return String.valueOf(result);177 }178 179 /**180 * 提供精确的小数位四舍五入处理。181 * 182 * @param v183 * 需要四舍五入的数字184 * @param scale185 * 小数点后保留几位186 * @return 四舍五入后的结果187 */188 public static String round(double v, int scale) {189 if (scale < 0) {190 throw new IllegalArgumentException(191 "The scale must be a positive integer or zero");192 }193 BigDecimal b = new BigDecimal(Double.toString(v));194 BigDecimal one = new BigDecimal("1");195 return String.valueOf(b.divide(one, scale, BigDecimal.ROUND_HALF_UP));196 }197 198 /**199 * 提供精确的小数位四舍五入处理。200 * 201 * @param v202 * 需要四舍五入的数字203 * @param scale204 * 小数点后保留几位205 * @return 四舍五入后的结果206 */207 public static String round(String v, int String, int scale) {208 if (scale < 0) {209 throw new IllegalArgumentException(210 "The scale must be a positive integer or zero");211 }212 BigDecimal b = new BigDecimal(v);213 BigDecimal one = new BigDecimal("1");214 215 b.divide(one, scale, BigDecimal.ROUND_HALF_UP);216 217 return null;218 }219 }