计算器在我们的日常生活中也扮演了一定的角色,在Android学习的过程中也是一样。在Android开发的前期很多都会自学做计算器,计算器不仅仅是简单,还是对自己掌握布局控件的一种检验,更重要的是对自己能力的一种测试。计算器虽然很简单,但是对初学者来说也是一种考验。这里我就不多说了,上代码,代码里面有很详细的注释。实现效果如下:
示例代码
package com.example.utils;
public class CalcTool {
// 主计算方法参数为一个混合运算字符串
public static String getCacluteMain(String str) {
String[] str1 = str.split("[+-]");
for (int i = 0; i < str1.length; i++) {
if (str1[i].indexOf("/") > 0 || str1[i].indexOf("*") > 0) {
str1[i] = getCaculateUnder(str1[i]);
}
}
char stdfc[] = str.toCharArray();
char stdf[] = new char[50];
int j = 0;
for (int i = 0; i < stdfc.length; i++) {
if (stdfc[i] == '+') {
stdf[j] = '+';
j++;
}
if (stdfc[i] == '-') {
stdf[j] = '-';
j++;
}
}
float stdd[] = new float[50];
for (int i = 0; i < str1.length; i++)
if (!str1[i].equals("")) {
stdd[i] = Float.parseFloat(str1[i]);
}
for (int i = 1; i < stdf.length; i++) {
if (stdf[i - 1] == '+')
stdd[0] += stdd[i];
if (stdf[i - 1] == '-')
stdd[0] -= stdd[i];
}
Float d = Float.valueOf(stdd[0]);
String result = d.toString();
return result;
}
// 此方法为私有方法只有主方法caculateMain()能调用;此方法用于计算含有“*/”高级字符串
private static String getCaculateUnder(String str) {
char stdf[] = new char[50];
float stdd[] = new float[50];
String stds[] = str.split("[/*]");
for (int i = 0; i < stds.length; i++)
stdd[i] = Float.parseFloat(stds[i]);
char stdfc[] = str.toCharArray();
int j = 0, count = 1;
for (int i = 0; i < stdfc.length; i++) {
if (stdfc[i] == '/') {
stdf[j] = '/';
j++;
count++;
}
if (stdfc[i] == '*') {
stdf[j] = '*';
j++;
count++;
}
}
for (int i = 1; i < count; i++) {
if (stdf[i - 1] == '/')
stdd[0] /= stdd[i];
if (stdf[i - 1] == '*')
stdd[0] *= stdd[i];
}
Float d = Float.valueOf(stdd[0]);
String result = d.toString();
return result;
}
// 此函数用于计算包含括号的字符串
public static String getCaculateHigh(String str) {
String[] str1;
str1 = str.split("[(]");
String str2;
str2 = getCacluteMain(str1[str1.length - 1]);
String str3;
str3 = "(" + str1[str1.length - 1];
str = str.replace(str3, str2);
return str;
}
// 判断.的位置
public static boolean isTrue(String str) {
boolean mFlag = false;
if (str.length() >= 0) {
String[] mFrist = str.split("[+-]");
if (mFrist.length > 0) {
for (int i = 0; i < mFrist.length; i++) {
if (mFrist[i].contains("*") || mFrist[i].contains
("/")) {
String[] mSencond = mFrist[i].split("[/*]");
for (int j = 0; j < mSencond.length; j++) {
if (mSencond[j].indexOf(".") ==
mSencond[j].lastIndexOf(".")) {
mFlag = true;
} else {
mFlag = false;
break;
}
}
} else {
if (mFrist[i].indexOf(".") == mFrist[i]
.lastIndexOf(".")) {
mFlag = true;
} else {
mFlag = false;
break;
}
}
}
}
} else {
return false;
}
return mFlag;
}
// 判断结果是否需要清空字符串
public static boolean isDigitEnd(String str) {
if (str.contains("=")) {
return true;
} else {
return false;
}
}
}
package com.example.calculator;
import com.example.utils.CalcTool;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class Calculator extends Activity {
// 数字按钮
private Button mBtn_1;
private Button mBtn_2;
private Button mBtn_3;
private Button mBtn_4;
private Button mBtn_5;
private Button mBtn_6;
private Button mBtn_7;
private Button mBtn_8;
private Button mBtn_9;
private Button mBtn_0;
private Button mBtn_add;
private Button mBtn_sub; // 减
private Button mBtn_multiply; // 乘
private Button mBtn_divide; // 除
private Button mBtn_del;// 删除一个
private Button mBtn_equals; // 等于
private Button mBtn_point; // 点
private Button mBtn_clean; // 清除
private EditText mEdt_play; // 显示运算过程
private TextView mTv_result;// 显示结果
// 显示输入的字符串
StringBuffer mStr_display = new StringBuffer();
// 暂存运算结果
String mStr_result = "";
// 存放运算符
String mStr_Oper = "";
// 单个字符
char mStr_char;
// 存放结果
double mValue;
String mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.calculator);
findView();
// 注册计算器按键的OnClick监听事件
BtnOnClick btn_OnClick = new BtnOnClick();
mBtn_0.setOnClickListener(btn_OnClick);
mBtn_1.setOnClickListener(btn_OnClick);
mBtn_2.setOnClickListener(btn_OnClick);
mBtn_3.setOnClickListener(btn_OnClick);
mBtn_4.setOnClickListener(btn_OnClick);
mBtn_5.setOnClickListener(btn_OnClick);
mBtn_6.setOnClickListener(btn_OnClick);
mBtn_7.setOnClickListener(btn_OnClick);
mBtn_8.setOnClickListener(btn_OnClick);
mBtn_9.setOnClickListener(btn_OnClick);
mBtn_add.setOnClickListener(btn_OnClick);
mBtn_sub.setOnClickListener(btn_OnClick);
mBtn_multiply.setOnClickListener(btn_OnClick);
mBtn_divide.setOnClickListener(btn_OnClick);
mBtn_point.setOnClickListener(btn_OnClick);
mBtn_equals.setOnClickListener(btn_OnClick);
mBtn_clean.setOnClickListener(btn_OnClick);
mBtn_del.setOnClickListener(btn_OnClick);
}
/**
* 注册控件ID
*/
private void findView() {
mBtn_0 = (Button) findViewById(R.id.btn_0);
mBtn_1 = (Button) findViewById(R.id.btn_1);
mBtn_2 = (Button) findViewById(R.id.btn_2);
mBtn_3 = (Button) findViewById(R.id.btn_3);
mBtn_4 = (Button) findViewById(R.id.btn_4);
mBtn_5 = (Button) findViewById(R.id.btn_5);
mBtn_6 = (Button) findViewById(R.id.btn_6);
mBtn_7 = (Button) findViewById(R.id.btn_7);
mBtn_8 = (Button) findViewById(R.id.btn_8);
mBtn_9 = (Button) findViewById(R.id.btn_9);
mBtn_add = (Button) findViewById(R.id.btn_calc_add);
mBtn_sub = (Button) findViewById(R.id.btn_sub);
mBtn_multiply = (Button) findViewById(R.id.btn_multiply);
mBtn_divide = (Button) findViewById(R.id.btn_divide);
mBtn_del = (Button) findViewById(R.id.btn_del);
mBtn_equals = (Button) findViewById(R.id.btn_equal);
mBtn_point = (Button) findViewById(R.id.btn_point);
mBtn_clean = (Button) findViewById(R.id.btn_clear);
mEdt_play = (EditText) findViewById(R.id.edt_calc);
mEdt_play.setText("");
mTv_result = (TextView) findViewById(R.id.txt_calc);
}
/**
*
* 按钮监听
*
*/
class BtnOnClick implements OnClickListener {
@Override
public void onClick(View v) {
// 如果mStr_display 这个StringBuffer对象存在
if (mStr_display != null) {
// 如果mStr_display里面包含有"="则实例化StringBuffer重新为mStr_display赋值
if (mStr_display.indexOf("=") != -1) {
mStr_display = new StringBuffer();
// 显示的字符串只含有运算结果
mStr_display.append(mValue);
// 如果显示的字符串是以".0"结尾的则删除后".0"
if (mStr_display.toString().endsWith(".0")) {
mStr_display.delete(mStr_display.length() - 2,
mStr_display.length());
}
mEdt_play.setText(mStr_display.toString());
}
// 如果显示的字符串是"无穷大","负无穷","错误数据"则实例化StringBuffer重新为mStr_display赋值
if (mStr_display.toString().equals("无穷大")
|| mStr_display.toString().equals("负无穷")
|| mStr_display.toString().equals("错误数据")) {
// 新建一个新的字符串根据其它点击的按钮事件进行相应的操作
mStr_display = new StringBuffer();
// 在输入框内显示输入的内容
mEdt_play.setText(mStr_display.toString());
}
// 根据被点按钮的Id响应相应按钮的事件
switch (v.getId()) {
// 点击0按钮的id事件
case R.id.btn_0:
mStr_display.append("0");
mEdt_play.setText(mStr_display.toString());
break;
// 点击1按钮的id事件
case R.id.btn_1:
/*
* 判断是否需要清空 如果之前已经运算过了 再次输入 则认为是一次新的计算过程 表示显示的内容
*/
if (mStr_display.length() != 0) {
// 调用CalcTool的isDigitEnd方法 判断是否有等号如果有等号则清空
if (CalcTool.isDigitEnd(mStr_result)) {
// 清空输入框内的内容
mStr_display = new StringBuffer();
// 在清空后的输入框内显示输入的数字1
mStr_display.append("1");
// 将运算的结果清空
mStr_result = "";
} else {
// 在输入框内显示的内容后面追加1
mStr_display.append("1");
}
} else {
// 在输入框内显示的内容后面追加1
mStr_display.append("1");
}
// 在输入框内显示已经输入的字符串
mEdt_play.setText(mStr_display.toString());
break;
// 点击2按钮的id事件
case R.id.btn_2:
/*
* 判断是否需要清空 如果之前已经运算过了 再次输入 则认为是一次新的计算过程 表示在输入数字时输入框内已经存在有内用
*/
if (mStr_display.length() != 0) {
// 调用CalcTool的isDigitEnd方法 判断是否有等号如果有等号则清空
if (CalcTool.isDigitEnd(mStr_result)) {
// 清空输入框内的内容
mStr_display = new StringBuffer();
// 在清空后的输入框内显示输入的数字2
mStr_display.append("2");
// 将暂存的结果设置为空,虽然在显示结果的文本框内显示但是与正在进行的新的运算已经没没有关系
mStr_result = "";
} else {
// 在输入框内显示的内容后面追加2
mStr_display.append("2");
}
} else {
// 在输入框显示的内容后面追加2
mStr_display.append("2");
}
// 在输入框内显示已存在和新输入的内容
mEdt_play.setText(mStr_display.toString());
break;
// 点击3按钮的id事件
case R.id.btn_3:
// 判断是否需要清空 如果之前已经运算过了 再次输入 则认为是一次新的计算过程
if (mStr_display.length() != 0) {// 表示有内容
// 调用CalcTool的isDigitEnd方法 判断是否有等号如果有等号则清空
if (CalcTool.isDigitEnd(mStr_result)) {
// 清空输入框内的内容
mStr_display = new StringBuffer();
mStr_display.append("3");
// 将暂存的结果设置为空,虽然在显示结果的文本框内显示但是与正在进行的新的运算已经没有关系
mStr_result = "";
} else {
// 在输入框内显示的内容后面追加3
mStr_display.append("3");
}
} else {
// 在输入框内显示的内容后面追加3
mStr_display.append("3");
}
// 在输入框内显示已存在和新输入的内容
mEdt_play.setText(mStr_display.toString());
break;
// 点击4按钮的id事件
case R.id.btn_4:
// 判断是否需要清空 如果之前已经运算过了 再次输入 则认为是一次新的计算过程
if (mStr_display.length() != 0) {// 表示有内容
// 调用CalcTool的isDigitEnd方法 判断是否有等号如果有等号则清空
if (CalcTool.isDigitEnd(mStr_result)) {
// 清空输入框内的内容
mStr_display = new StringBuffer();
mStr_display.append("4");
// 将暂存的结果设置为空,虽然在显示结果的文本框内显示但是与正在进行的新的运算已经没有关系
mStr_result = "";
} else {
// 在输入框内显示的内容后面追加4
mStr_display.append("4");
}
} else {
// 在输入框内显示的内容后面追加4
mStr_display.append("4");
}
// 在输入框内显示已存在和新输入的内容
mEdt_play.setText(mStr_display.toString());
break;
// 点击5按钮的id事件
case R.id.btn_5:
// 判断是否需要清空 如果之前已经运算过了 再次输入 则认为是一次新的计算过程
if (mStr_display.length() != 0) {// 表示有内容
// 调用CalcTool的isDigitEnd方法 判断是否有等号如果有等号则清空
if (CalcTool.isDigitEnd(mStr_result)) {
// 清空输入框内的内容
mStr_display = new StringBuffer();
// 在输入框内显示的内容后面追加5
mStr_display.append("5");
// 将暂存的结果设置为空,虽然在显示结果的文本框内显示但是与正在进行的新的运算已经没有关系
mStr_result = "";
} else {// 追加5
// 在输入框内显示的内容后面追加5
mStr_display.append("5");
}
} else {
// 在输入框内显示的内容后面追加5
mStr_display.append("5");
}
// 在输入框内显示已存在和新输入的内容
mEdt_play.setText(mStr_display.toString());
break;
// 点击6按钮的id事件
case R.id.btn_6:
// 判断是否需要清空 如果之前已经运算过了 再次输入 则认为是一次新的计算过程
if (mStr_display.length() != 0) {// 表示有内容
// 调用CalcTool的isDigitEnd方法 判断是否有等号如果有等号则清空
if (CalcTool.isDigitEnd(mStr_result)) {
// 清空输入框内的内容
mStr_display = new StringBuffer();
mStr_display.append("6");
// 将暂存的结果设置为空,虽然在显示结果的文本框内显示但是与正在进行的新的运算已经没有关系
mStr_result = "";
} else {
// 在输入框内显示的内容后面追加6
mStr_display.append("6");
}
} else {
// 在输入框内显示的内容后面追加6
mStr_display.append("6");
}
// 在输入框内显示已存在和新输入的内容
mEdt_play.setText(mStr_display.toString());
break;
// 点击7按钮的id事件
case R.id.btn_7:
// 判断是否需要清空 如果之前已经运算过了 再次输入 则认为是一次新的计算过程
if (mStr_display.length() != 0) {// 表示有内容
// 调用CalcTool的isDigitEnd方法 判断是否有等号如果有等号则清空
if (CalcTool.isDigitEnd(mStr_result)) {
// 清空输入框内的内容
mStr_display = new StringBuffer();
mStr_display.append("7");
// 将暂存的结果设置为空,虽然在显示结果的文本框内显示但是与正在进行的新的运算已经没有关系
mStr_result = "";
} else {// 追加7
mStr_display.append("7");
}
} else {// 追加7
mStr_display.append("7");
}
// 在输入框内显示已存在和新输入的内容
mEdt_play.setText(mStr_display.toString());
break;
// 点击8按钮的id事件
case R.id.btn_8:
// 判断是否需要清空 如果之前已经运算过了 再次输入 则认为是一次新的计算过程
if (mStr_display.length() != 0) {// 表示有内容
// 调用CalcTool的isDigitEnd方法 判断是否有等号如果有等号则清空
if (CalcTool.isDigitEnd(mStr_result)) {
// 清空输入框内的内容
mStr_display = new StringBuffer();
mStr_display.append("8");
// 将暂存的结果设置为空,虽然在显示结果的文本框内显示但是与正在进行的新的运算已经没有关系
mStr_result = "";
} else {// 追加8
mStr_display.append("8");
}
} else {// 追加8
mStr_display.append("8");
}
// 在输入框内显示已存在和新输入的内容
mEdt_play.setText(mStr_display.toString());
break;
// 点击9按钮的id事件
case R.id.btn_9:
// 判断是否需要清空 如果之前已经运算过了 再次输入 则认为是一次新的计算过程
if (mStr_display.length() != 0) {// 表示有内容
// 调用CalcTool的isDigitEnd方法 判断是否有等号如果有等号则清空
if (CalcTool.isDigitEnd(mStr_result)) {
// 清空输入框内的内容
mStr_display = new StringBuffer();
mStr_display.append("9");
// 将暂存的结果设置为空,虽然在显示结果的文本框内显示但是与正在进行的新的运算已经没有关系
mStr_result = "";
} else {// 追加9
mStr_display.append("9");
}
} else {// 追加9
mStr_display.append("9");
}
// 在输入框内显示已存在和新输入的内容
mEdt_play.setText(mStr_display.toString());
break;
case R.id.btn_calc_add:// 符号键"+"单击事件
mStr_result = "";
// 判断是否是以"/0"结尾的
if (mStr_display.toString().endsWith("/0")) {
//如果是以"/0"结尾的就提示
Toast.makeText(Calculator.this, "除数不能为0",
Toast.LENGTH_SHORT).show();
mStr_display.delete(mStr_display.length() - 2,
mStr_display.length());
mEdt_play.setText(mStr_display.toString());
} else {
mStr_Oper = "+";
// 如果显示的不为空
if (!(mStr_display.toString() == "")) {
// 得到最后一个位置的字符,字符可能是数字也可能是运算符
mStr_char = mStr_display.charAt(mStr_display
.length() - 1);
// 判断最后一位是否是数字
if (Character.isDigit(mStr_char)) {
mStr_display.append(mStr_Oper);
mEdt_play.setText(mStr_display.toString());
}
}
}
break;
case R.id.btn_sub:// 符号键"-"单击事件
mStr_result = "";
// 考虑是否是"/0"结尾的
if (mStr_display.toString().endsWith("/0")) {
// 如果是则显示"除数不能为0"的Toast提示
Toast.makeText(Calculator.this, "除数不能为0",
Toast.LENGTH_SHORT).show();
// 如果是以"/0"结尾则删除"/0"
mStr_display.delete(mStr_display.length() - 2,
mStr_display.length());
mEdt_play.setText(mStr_display.toString());
} else {
mStr_Oper = "-";
// 如果显示的内容不为空
if (mStr_display.length() != 0) {
// 得到最后一个位置的字符,字符可能是数字也可能是运算符
mStr_char = mStr_display.charAt(mStr_display
.length() - 1);
// 判断最后一位是否是数字
if (Character.isDigit(mStr_char)) {
mStr_display.append(mStr_Oper);
mEdt_play.setText(mStr_display.toString());
}
}
if (mStr_display.length() == 0) {
mStr_display.append("-");
mEdt_play.setText(mStr_display.toString());
}
}
break;
case R.id.btn_multiply:// 符号键"*"单击事件
mStr_result = "";
// 考虑是否是/0结尾的
if (mStr_display.toString().endsWith("/0")) {
// 如果是则
Toast.makeText(Calculator.this, "除数不能为0",
Toast.LENGTH_SHORT).show();
mStr_display.delete(mStr_display.length() - 2,
mStr_display.length());
mEdt_play.setText(mStr_display.toString());
} else {
mStr_Oper = "*";
if (mStr_display.toString() != "") {
// 得到最后一个位置的字符
mStr_char = mStr_display.charAt(mStr_display
.length() - 1);
// 如果得到的最后一位是数字
if (Character.isDigit(mStr_char)) {
// 在已存在的内容后面追加"*"
mStr_display.append("*");
mEdt_play.setText(mStr_display.toString());
}
}
}
break;
case R.id.btn_divide:// 符号键"/"单击事件
mStr_result = "";
// 考虑是否是/0结尾的
if (mStr_display.toString().endsWith("/0")) {
// 如果是则显示"除数不能为0”的Toast提示
Toast.makeText(Calculator.this, "除数不能为0",
Toast.LENGTH_SHORT).show();
// 如果显示的字符串包含有"/0"则删除"/0"
mStr_display.delete(mStr_display.length() - 2,
mStr_display.length());
mEdt_play.setText(mStr_display.toString());
} else {
mStr_Oper = "/";
if (mStr_display.toString() != "") {
mStr_char = mStr_display.charAt(mStr_display
.length() - 1);// 得到最后一个位置的字符
if (Character.isDigit(mStr_char)) {
mStr_display.append(mStr_Oper);
mEdt_play.setText(mStr_display.toString());
}
}
}
break;
case R.id.btn_point:// 符号键"."单击事件
if (mStr_display.length() == 0) {
mStr_display.append("0.");
mEdt_play.setText(mStr_display.toString());
} else {
if (mStr_display.toString().endsWith("+")
|| mStr_display.toString().endsWith("-")
|| mStr_display.toString().endsWith("*")
|| mStr_display.toString().endsWith("/")) {
mStr_display.append("0.");
mEdt_play.setText(mStr_display.toString());
} else if (mStr_display.toString().contains(".")
&& !mStr_display.toString().contains("+")
&& !mStr_display.toString().contains("-")
&& !mStr_display.toString().contains("*")
&& !mStr_display.toString().contains("/")) {
mEdt_play.setText(mStr_display.toString());
// 如果一个. 返回true 再次 按 . 返回false
} else {
mStr_display.append(".");
mEdt_play.setText(mStr_display.toString());
}
// 当前有 . 如果再次按. 就删除掉原来的.
if (!CalcTool.isTrue(mStr_display.toString())) {
mStr_display
.deleteCharAt(mStr_display.length() - 1);
}
}
break;
case R.id.btn_equal:// 符号键"="单击事件
if (mStr_display.length() != 0) {// 如果串不为空
// 如果串中拥有+-*/运算符
if (mStr_display.toString().indexOf("+") != -1
|| mStr_display.toString().indexOf("-") != -1
|| mStr_display.toString().indexOf("*") != -1
|| mStr_display.toString().indexOf("/") != -1) {
// 判断结尾是否是+-*/.
// 判断结尾是否是数字
if (mStr_display.toString().charAt(
mStr_display.length() - 1) != '+'
&& mStr_display.toString().charAt(
mStr_display.length() - 1) != '-'
&& mStr_display.toString().charAt(
mStr_display.length() - 1) != '*'
&& mStr_display.toString().charAt(
mStr_display.length() - 1) != '/'
&& mStr_display.toString().charAt(
mStr_display.length() - 1) != '.') {
try {
mValue = Double.parseDouble(CalcTool
.getCacluteMain(mStr_display
.toString()));
mStr_display = new StringBuffer();
if (mValue >= Float.MAX_VALUE) {
mStr_display.append("无穷大");
} else if (mValue <= -Float.MAX_VALUE) {
mStr_display.append("负无穷");
} else {
mStr_display.append("=");
mStr_display.append(mValue);
if (mStr_display.toString().endsWith(
".0")) {
mStr_display.delete(mStr_display
.toString().length() - 2,
mStr_display.toString()
.length());
}
}
} catch (NumberFormatException e) {
mStr_display = new StringBuffer();
mStr_display.append("错误数据");
}
mStr_result = mStr_display.toString();
mTv_result.setText(mStr_display.toString());
}
}
}
break;
case R.id.btn_clear:// 清空按钮事件
mStr_display = new StringBuffer();
mStr_result = "";
mEdt_play.setText("");
mTv_result.setText("");
break;
case R.id.btn_del:// 退格按钮事件
if (mStr_display.length() != 0) {
mStr_display.deleteCharAt(mStr_display.length() - 1);
mEdt_play.setText(mStr_display.toString());
}
if (mStr_display.length() == 0) {
mEdt_play.setText("");
}
break;
}
}
}
}
}