下载链接:http://download.csdn.net/detail/tomi_en/9427474
一、计算器界面设计
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/myLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<EditText
android:id="@+id/result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|right"
android:height="70dip"
android:numeric="decimal"
android:scrollbars="none"
android:text="0"
android:textSize="30sp" >
</EditText>
<TableLayout
android:id="@+id/buttonArea"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TableRow
android:layout_width="fill_parent"
android:layout_height="70dip"
android:layout_span="4"
android:gravity="right" >
<Button
android:id="@+id/btnDel"
android:layout_width="80dip"
android:layout_height="50dip"
android:onClick="onButtonClickHandler"
android:text="del"
android:textSize="20sp"
android:textStyle="bold" >
</Button>
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="70dip" >
<Button
android:id="@+id/btn7"
android:layout_width="80dip"
android:layout_height="70dip"
android:gravity="center"
android:onClick="onButtonClickHandler"
android:text="7"
android:textSize="30sp"
android:textStyle="bold" >
</Button>
<Button
android:id="@+id/btn8"
android:layout_width="80dip"
android:layout_height="70dip"
android:gravity="center"
android:onClick="onButtonClickHandler"
android:text="8"
android:textSize="30sp"
android:textStyle="bold" >
</Button>
<Button
android:id="@+id/btn9"
android:layout_width="80dip"
android:layout_height="70dip"
android:gravity="center"
android:onClick="onButtonClickHandler"
android:text="9"
android:textSize="30sp"
android:textStyle="bold" >
</Button>
<Button
android:id="@+id/btnAdd"
android:layout_width="80dip"
android:layout_height="70dip"
android:gravity="center"
android:onClick="onButtonClickHandler"
android:text="+"
android:textSize="30sp"
android:textStyle="bold" >
</Button>
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="70dip" >
<Button
android:id="@+id/btn4"
android:layout_width="80dip"
android:layout_height="70dip"
android:gravity="center"
android:onClick="onButtonClickHandler"
android:text="4"
android:textSize="30sp"
android:textStyle="bold" >
</Button>
<Button
android:id="@+id/btn5"
android:layout_width="80dip"
android:layout_height="70dip"
android:gravity="center"
android:onClick="onButtonClickHandler"
android:text="5"
android:textSize="30sp"
android:textStyle="bold" >
</Button>
<Button
android:id="@+id/btn6"
android:layout_width="80dip"
android:layout_height="70dip"
android:gravity="center"
android:onClick="onButtonClickHandler"
android:text="6"
android:textSize="30sp"
android:textStyle="bold" >
</Button>
<Button
android:id="@+id/btnMinus"
android:layout_width="80dip"
android:layout_height="70dip"
android:gravity="center"
android:onClick="onButtonClickHandler"
android:text="-"
android:textSize="30sp"
android:textStyle="bold" >
</Button>
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="70dip" >
<Button
android:id="@+id/btn1"
android:layout_width="80dip"
android:layout_height="70dip"
android:gravity="center"
android:onClick="onButtonClickHandler"
android:text="1"
android:textSize="30sp"
android:textStyle="bold" >
</Button>
<Button
android:id="@+id/btn2"
android:layout_width="80dip"
android:layout_height="70dip"
android:gravity="center"
android:onClick="onButtonClickHandler"
android:text="2"
android:textSize="30sp"
android:textStyle="bold" >
</Button>
<Button
android:id="@+id/btn3"
android:layout_width="80dip"
android:layout_height="70dip"
android:gravity="center"
android:onClick="onButtonClickHandler"
android:text="3"
android:textSize="30sp"
android:textStyle="bold" >
</Button>
<Button
android:id="@+id/btnMultiply"
android:layout_width="80dip"
android:layout_height="70dip"
android:gravity="center"
android:onClick="onButtonClickHandler"
android:text="*"
android:textSize="30sp"
android:textStyle="bold" >
</Button>
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="70dip" >
<Button
android:id="@+id/btn0"
android:layout_width="80dip"
android:layout_height="70dip"
android:gravity="center"
android:onClick="onButtonClickHandler"
android:text="0"
android:textSize="30sp"
android:textStyle="bold" >
</Button>
<Button
android:id="@+id/btnPoint"
android:layout_width="80dip"
android:layout_height="70dip"
android:gravity="center"
android:onClick="onButtonClickHandler"
android:text="."
android:textSize="30sp"
android:textStyle="bold" >
</Button>
<Button
android:id="@+id/btnEqual"
android:layout_width="80dip"
android:layout_height="70dip"
android:gravity="center"
android:onClick="onButtonClickHandler"
android:text="="
android:textSize="30sp"
android:textStyle="bold" >
</Button>
<Button
android:id="@+id/btnDivide"
android:layout_width="80dip"
android:layout_height="70dip"
android:gravity="center"
android:onClick="onButtonClickHandler"
android:text="÷"
android:textSize="30sp"
android:textStyle="bold" >
</Button>
</TableRow>
</TableLayout>
</LinearLayout>
平时所见的计算器都是网格状的,所以用TableLayout。EditText中的android:gravity:是针对控件里的元素,用来控制元素在该控件里的显示位置。还有一种布局是android:layout_gravity是针对控件本身而言,用来控制该控件在包含该控件的父控件中的位置。一个属性可以包含多个值,需用“|”分开。Layout _width ,layout_height作用是设置控件相对于父容器的大小,一个控件里必须有Layout _width ,layout_height,但height和width不是必须的。height也是针对控件的,只不过是layout_height的微调。numeric是数值型的意思,decimal是小数的意思。scrollbars是滚动条的意思,设为none保证了EditText只有一行。
android:layout_span=”4”合并单元格,因为这一行只有一个键,所以合并成一个单元格。OnClick点击事件,方法在activity中实现。
二、逻辑代码
计算器最关键的两点就是按键和显示,我们从这两方面考虑就可以设计出一个很好的计算器了。
设置了四个变量,operator表示运算符,oldText表示参与运算的第一个数字,inputdone表示是否继续输入,operatorNumber表示参与运算的第二个数字。具体的思路是这样的,比如说计算12+3-1=?一开始,变量operator,oldText,operatorNumber值为空,inputdone设为true,点击1后,inputdone变为false,operatorNumber为1;点击2后,operatorNumber为12;点击+号,operator为+,oldText为12,inputdone变为true;点击3后,operatorNumber为3;点击 - 号,执行函数calculate(),显示为15,operator为 -,oldText为15,inputdone变为true;点击1,operatorNumber为1;点击=,执行函数calculate()显示为14,operator为 =,oldText为14,inputdone变为true。
public class MainActivity extends Activity implements OnTouchListener,
OnLongClickListener {
private EditText et;
private String operator = "";
private String oldText = "";
private boolean inputDone = true;
private String operatorNumber = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et = (EditText) findViewById(R.id.result);
Button delBtn = (Button) findViewById(R.id.btnDel);
delBtn.setOnLongClickListener(this);
et.setOnTouchListener(this);
}
public void onButtonClickHandler(View view) {
Button button = (Button) view;
if ("del".equals(button.getText())) {
String s = String.valueOf(et.getText());
if (s.length() > 0) {
if (s.length() == 1) {
clear("0");
} else {// 截取字符
et.setText(s.subSequence(0, s.length() - 1));
}
operatorNumber = et.getText().toString();
}
} else if ("+".equals(button.getText()) || "-".equals(button.getText())
|| "*".equals(button.getText()) || "÷".equals(button.getText())
|| "=".equals(button.getText())) {
calculate();
operator = button.getText().toString();
oldText = et.getText().toString();
inputDone = true;
} else {
if (inputDone) {
et.setText(button.getText().toString());
inputDone = false;
} else {
et.append(button.getText().toString());
}
operatorNumber = et.getText().toString();
}
et.requestFocus(TextView.FOCUS_RIGHT);// 获取焦点
}
private void calculate() {
if ("+".equals(operator)) {
et.setText(String.valueOf(Arith.add(oldText, operatorNumber)));
} else if ("-".equals(operator)) {
et.setText(String.valueOf(Arith.sub(oldText, operatorNumber)));
} else if ("*".equals(operator)) {
et.setText(String.valueOf(Arith.mul(oldText, operatorNumber)));
} else if ("÷".equals(operator)) {
if ("0".equals(operatorNumber)) {
clear("被除数不能为零");
} else {
et.setText(String.valueOf(Arith.div(oldText, operatorNumber)));
}
}
}
private void clear(String text) {
et.setText(text);
operator = "";
oldText = "";
operatorNumber = "";
inputDone = true;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
et.setInputType(InputType.TYPE_NULL);
return false;
}
@Override
public boolean onLongClick(View v) {
clear("0");
return false;
}
}
三、Arith类
public class Arith {
// 默认除法运算精度
private static final int DEF_DIV_SCALE = 10;
// 这个类不能实例化
private Arith() {
;
}
// 加法运算
public static String add(String v1, String v2) {
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return String.valueOf(b1.add(b2));
}
// 减法运算
public static String sub(String v1, String v2) {
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return String.valueOf(b1.subtract(b2));
}
// 乘法运算
public static String mul(String v1, String v2) {
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return String.valueOf(b1.multiply(b2));
}
// 除法运算
public static String div(String v1, String v2) {
return div(v1, v2, DEF_DIV_SCALE);
}
// 当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。
public static String div(String v1, String v2, int scale) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
BigDecimal result = null;
try {
result = b1.divide(b2);
} catch (Exception e) {
result = b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP);
}
return String.valueOf(result);
}
}