1.效果
2.搭建布局
根布局使用LinearLayout——线性布局实现,其中布局方向设置为垂直排列即可。
android:orientation="vertical"
TextView——文本视图:
属性 | 值 | 含义 |
android:layout_margin | 数字+dip 或 数字+dp | 控件距离指定的父控件边缘的距离 其中layout_margin表示同时距离 四个父控件边缘的距离 |
| 数字+sp | 控件显示的字体大小 |
| 颜色值 | 控件显示的字体颜色 |
| -- | 控件中字体的重心 |
由于计算器显示的数字是向右对其的,因此设置gravity属性为“right”,并且可以再加上垂直居中属性,使文字显示在textview的上下中间,如下:
android:gravity="right|center_vertical"
GridLayout——网格布局:
属性 | 值 | 含义 |
|
| 布局的排列方式 |
|
| 网格的最大列/行数 |
|
| 子控件的权重 |
|
| 子控件的列/行的坐标 |
|
| 子控件的行的坐标 |
|
| 子控件所占的列/行数 |
实现计算机键盘布局的难点在于“0”键和“=”键分别要占用两列和两行,此时我们需要使用layout_columnSpan和layout_rowSpan属性设置这两个button,其他button按序排列即可:
比较坑的是:如果你的其他Button的宽高设置为“wrap_content”,就算最后设置了“0”键和“=”键占用的行数或列数,
也并不会起作用,只显示占用了一行/列,并且不会充满整余下个屏幕,这个时候就用到了“widght”权重属性,我们给所有button都加上
android:layout_height="0dp"
android:layout_rowWeight="1"
这个时候整个键盘就会充满剩下的屏幕,因为他们的“layout_rowWeight”权重都相同,所以android会把剩余屏幕部分平均分给每个button的“height”高属性。
但是又出现一下情况:
这是因为“0”键的宽度还是“wrap_content”,改为如下属性即可,至此计算器布局OK!
android:layout_columnWeight="1"
android:layout_width="0dp"
计算器按键布局如下:
<GridLayout
android:id="@+id/gl_calculator_keys"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_margin="10dip"
android:alignmentMode="alignBounds"
android:columnCount="4"
android:orientation="horizontal"
android:rowCount="6"
android:layout_weight="1">
<Button
android:id="@+id/btn_key_01"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_column="0"
android:layout_row="0"
android:layout_rowWeight="1"
android:text="MC" />
<Button
android:id="@+id/btn_key_02"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_column="1"
android:layout_row="0"
android:layout_rowWeight="1"
android:text="M+" />
<Button
android:id="@+id/btn_key_03"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_column="2"
android:layout_row="0"
android:layout_rowWeight="1"
android:text="M-" />
<Button
android:id="@+id/btn_key_04"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_column="3"
android:layout_row="0"
android:layout_rowWeight="1"
android:text="MR" />
<Button
android:id="@+id/btn_key_clear"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_column="0"
android:layout_row="1"
android:layout_rowWeight="1"
android:text="C" />
<Button
android:id="@+id/btn_key_type_div"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_column="1"
android:layout_row="1"
android:layout_rowWeight="1"
android:text="÷" />
<Button
android:id="@+id/btn_key_type_mul"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_column="2"
android:layout_row="1"
android:layout_rowWeight="1"
android:text="X" />
<Button
android:id="@+id/btn_key_backspace"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_column="3"
android:layout_row="1"
android:layout_rowWeight="1"
android:text="→" />
<Button
android:id="@+id/btn_key_num7"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_column="0"
android:layout_row="2"
android:layout_rowWeight="1"
android:text="7" />
<Button
android:id="@+id/btn_key_num8"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_column="1"
android:layout_row="2"
android:layout_rowWeight="1"
android:text="8" />
<Button
android:id="@+id/btn_key_num9"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_column="2"
android:layout_row="2"
android:layout_rowWeight="1"
android:text="9" />
<Button
android:id="@+id/btn_key_type_sub"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_column="3"
android:layout_row="2"
android:layout_rowWeight="1"
android:text="-" />
<Button
android:id="@+id/btn_key_num4"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_column="0"
android:layout_row="3"
android:layout_rowWeight="1"
android:text="4" />
<Button
android:id="@+id/btn_key_num5"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_column="1"
android:layout_row="3"
android:layout_rowWeight="1"
android:text="5" />
<Button
android:id="@+id/btn_key_num6"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_column="2"
android:layout_row="3"
android:layout_rowWeight="1"
android:text="6" />
<Button
android:id="@+id/btn_key_type_add"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_column="3"
android:layout_row="3"
android:layout_rowWeight="1"
android:text="+" />
<Button
android:id="@+id/btn_key_num1"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_column="0"
android:layout_row="4"
android:layout_rowWeight="1"
android:text="1" />
<Button
android:id="@+id/btn_key_num2"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_column="1"
android:layout_row="4"
android:layout_rowWeight="1"
android:text="2" />
<Button
android:id="@+id/btn_key_num3"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_column="2"
android:layout_row="4"
android:layout_rowWeight="1"
android:text="3" />
<Button
android:id="@+id/btn_key_equals"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_column="3"
android:layout_row="4"
android:layout_rowSpan="2"
android:layout_rowWeight="2"
android:text="=" />
<Button
android:id="@+id/btn_key_num0"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_column="0"
android:layout_row="5"
android:layout_columnSpan="2"
android:layout_columnWeight="2"
android:layout_rowWeight="1"
android:text="0" />
<Button
android:id="@+id/btn_key_point"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_column="2"
android:layout_row="5"
android:layout_rowWeight="1"
android:text="." />
</GridLayout>
3.业务代码实现
原理:
1.通过按下键盘的数字按键改变TextView显示的数值;
2.当按下计算规则按键时,先从TextView中读取数据,存入第一个变量,并设置计算类型;
改变TextView显示的数值;
4.当按下等号时,从TextView中读取数据,存入第二个变量,并取得计算结果,显示在TextView上。
MainActivity主要实现button的Onclick事件和键值获取:
case R.id.btn_key_clear:
calculator.clear();
showResult.setText("0");
showProcess.setText("");
break;
case R.id.btn_key_backspace:
calculator.backspace();
showResult.setText(calculator.getTempNum());
break;
case R.id.btn_key_num0:setNum(0);break;
case R.id.btn_key_num1:setNum(1);break;
case R.id.btn_key_num2:setNum(2);break;
case R.id.btn_key_num3:setNum(3);break;
case R.id.btn_key_num4:setNum(4);break;
case R.id.btn_key_num5:setNum(5);break;
case R.id.btn_key_num6:setNum(6);break;
case R.id.btn_key_num7:setNum(7);break;
case R.id.btn_key_num8:setNum(8);break;
case R.id.btn_key_num9:setNum(9);break;
case R.id.btn_key_type_div:setType(Calculator.Type.Division);break;
case R.id.btn_key_type_mul:setType(Calculator.Type.Multiplication);break;
case R.id.btn_key_type_sub:setType(Calculator.Type.Subtraction);break;
case R.id.btn_key_type_add:setType(Calculator.Type.Addition);break;
case R.id.btn_key_equals:
if(calculator.getType()!= Calculator.Type.Null) {
String str = showProcess.getText().toString();
str = str + showResult.getText().toString()+" = ";
showProcess.setText(str);
showResult.setText(calculator.getResult());
calculator.clear();
}
break;
case R.id.btn_key_point:
if(calculator.hasPoint())
break;
calculator.setPoint(true);
showResult.setText(String.format("%s.", showResult.getText().toString()));
break;
计算功能的实现代码如下:
package com.tz.bflyff.calculator;
import android.util.Log;
/**
*
* Created by Ice Nation on 2018/3/27.
*/
public class Calculator {
//第一个输入的数字
private double firstNum;
//第二个输入的数字
private double secondNum;
//当前正在输入的数字
private String temp = "0";
private boolean hasPoint = false;
private Type type = Type.Null;
public enum Type {
Addition, //加法
Subtraction, //减法
Multiplication, //乘法
Division, //除法
Null; //未输入运算符
}
public boolean hasPoint() {
return hasPoint;
}
//添加小数点
public void setPoint(boolean hasPoint) {
this.hasPoint = hasPoint;
if(hasPoint)
temp += ".";
}
/**
* 正在输入的数字添加末尾数字
* @param num 要添加的数字
*/
public void setNum(int num){
if(temp.length()>=12)
return;
if (temp.equals("0")){
temp = "";
}
temp += num + "";
}
//退格按键
public void backspace(){
if(temp.length()>1)
temp = temp.substring(0,temp.length()-1);
else temp = "0";
}
//清除按键
public void clear(){
temp = "";
type = Type.Null;
firstNum = 0;
secondNum = 0;
hasPoint = false;
}
public String getTempNum(){
return temp;
}
/**
* 设置计算类型 当输入运算符时有效
* @param type 计算器计算类型
*/
public void setType(Type type){
if(this.type != Type.Null)
return;
this.type = type;
firstNum = Double.valueOf(temp);
temp = "0";
}
public Type getType() {
return type;
}
//获取计算结果
public String getResult(){
secondNum = Double.valueOf(temp);;
temp = "0";
double result = 0.0f;
switch (type){
case Addition: result = DoubleUtil.add(firstNum,secondNum);break;
case Subtraction: result = DoubleUtil.sub(firstNum,secondNum);break;
case Multiplication: result = DoubleUtil.mul(firstNum,secondNum);break;
case Division:
//0不能做除数
if(secondNum == 0) {
return "出错";
}
result = DoubleUtil.divide(firstNum,secondNum);break;
default: break;
}
Log.i(getClass().getSimpleName(),"type = " + type.name());
Log.i(getClass().getSimpleName(),result+"");
long resultInt = (long) result;
if(result-resultInt>0.0d){
return Double.toString(result);
}else {
return Long.toString(resultInt);
}
}
public String getTypeString() {
switch (type){
case Addition: return " + ";
case Subtraction: return " - ";
case Multiplication: return " x ";
case Division: return " ÷ ";
default: return "";
}
}
}
MC M+ M- MR四个功能暂时没有实现,有兴趣的同学可以实现一下;