前言
其实学习了这么多的Android理论知识,还是需要做一点东西实践一下的,一来是借着项目回顾一下自己所学的东西并尽可能的将这些知识用上,二来就是熟悉一下Android的开发过程,毕竟学习Android肯定是要写出来几个像样点的APP嘛。所以综上,开设了Android实战系列。
第一个实战的项目就是一个Android计算器了,因为是自己第一次实战,所以说功能相对简易一些,而且可能会有一些小bug是我没有发现的。所以还请大佬们多多指教了。
ok,废话不多说,上代码!!!
https://github.com/yzbkaka/simple-calculator
源代码详解
1.布局
首先是计算器的整体布局,我的整体布局如图所示:
首先是看到最上面的显示白框,在这里我是使用了五个TextView,其中第一个TextView是用来显示我们进行计算的第一个数,第二个TextView是用来显示计算符号,第三个是进行计算的第二个数,第四个是来显示计算的等号,而最后一个是用来显示计算答案的,我这里的布局是前四个TextView是一起占据了第一行,而最后一个TextView是独自在下面占了一整行。
接着是下面按钮的布局,我这里的布局比较的简单,就是使用5个水平排列的LinearLayout,并在每个LinearLayout中放置4个按钮,并且让这些按钮平均分配父布局的宽度。
这是我的布局代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<TextView
android:id="@+id/the_first_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="50dp" />
<TextView
android:id="@+id/the_option"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="50dp" />
<TextView
android:id="@+id/the_second_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="50dp" />
<TextView
android:id="@+id/the_equal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="50dp"
android:maxLines="1"/>
<TextView
android:id="@+id/the_answer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="50dp"/>
</LinearLayout>
<View
android:layout_width="wrap_content"
android:layout_height="2dp"
android:background="#000"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<Button
android:id="@+id/surplus"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:textSize="30sp"
android:text="%" />
<Button
android:id="@+id/root"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="√"
android:textSize="30sp"/>
<Button
android:id="@+id/clear"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="C"
android:textSize="30sp"/>
<Button
android:id="@+id/delete"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="DEL"
android:textSize="30sp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<Button
android:id="@+id/seven"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="7"
android:textSize="30sp"/>
<Button
android:id="@+id/eight"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="8"
android:textSize="30sp"/>
<Button
android:id="@+id/nine"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="9"
android:textSize="30sp"/>
<Button
android:id="@+id/substraction"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="-"
android:textSize="30sp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<Button
android:id="@+id/four"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="4"
android:textSize="30sp"/>
<Button
android:id="@+id/five"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="5"
android:textSize="30sp"/>
<Button
android:id="@+id/six"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="6"
android:textSize="30sp"/>
<Button
android:id="@+id/add"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="+"
android:textSize="30sp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<Button
android:id="@+id/one"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="1"
android:textSize="30sp"/>
<Button
android:id="@+id/two"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="2"
android:textSize="30sp"/>
<Button
android:id="@+id/three"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="3"
android:textSize="30sp"/>
<Button
android:id="@+id/division"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="÷"
android:textSize="30sp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<Button
android:id="@+id/zero"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="0"
android:textSize="30sp"/>
<Button
android:id="@+id/point"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="."
android:textSize="30sp"/>
<Button
android:id="@+id/equal"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="="
android:textSize="30sp"/>
<Button
android:id="@+id/mulitipliction"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="×"
android:textSize="30sp"/>
</LinearLayout>
</LinearLayout>
2.主代码
因为计算器的功能比较少,所以这里就只有一个活动。我们在活动中的第一步就是为每一个按钮注册监听,这里我们让主活动继承自View.OnClickListener会更加的方便:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Button zero;
Button one;
Button two;
Button three;
Button four;
Button five;
Button six;
Button seven;
Button eight;
Button nine;
Button point;
Button clear;
Button add;
Button substraction;
Button mulitipliction;
Button division;
Button root;
Button surplus;
Button equal;
Button delete;
TextView theFirstView;
TextView theOptionView;
TextView theSecondView;
TextView theEqualView;
TextView theAnswerView;
String option = "";
String str1 = "",str2 = "";
double number1 ,number2;
int answerFlag = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView(); //初始化布局
}
public void initView(){
zero = (Button)findViewById(R.id.zero);
one = (Button)findViewById(R.id.one);
two = (Button)findViewById(R.id.two);
three = (Button)findViewById(R.id.three);
four = (Button)findViewById(R.id.four);
five = (Button)findViewById(R.id.five);
six = (Button)findViewById(R.id.six);
seven = (Button)findViewById(R.id.seven);
eight = (Button)findViewById(R.id.eight);
nine = (Button)findViewById(R.id.nine);
point = (Button)findViewById(R.id.point);
clear = (Button)findViewById(R.id.clear);
add = (Button)findViewById(R.id.add);
substraction = (Button)findViewById(R.id.substraction);
mulitipliction = (Button)findViewById(R.id.mulitipliction);
division = (Button)findViewById(R.id.division);
root = (Button)findViewById(R.id.root);
surplus = (Button)findViewById(R.id.surplus);
equal = (Button)findViewById(R.id.equal);
delete = (Button)findViewById(R.id.delete);
theFirstView = (TextView)findViewById(R.id.the_first_number);
theOptionView = (TextView)findViewById(R.id.the_option);
theSecondView = (TextView)findViewById(R.id.the_second_number);
theEqualView = (TextView)findViewById(R.id.the_equal);
theAnswerView = (TextView)findViewById(R.id.the_answer);
zero.setOnClickListener(this);
one.setOnClickListener(this);
two.setOnClickListener(this);
three.setOnClickListener(this);
four.setOnClickListener(this);
five.setOnClickListener(this);
six.setOnClickListener(this);
seven.setOnClickListener(this);
eight.setOnClickListener(this);
nine.setOnClickListener(this);
point.setOnClickListener(this);
clear.setOnClickListener(this);
add.setOnClickListener(this);
substraction.setOnClickListener(this);
mulitipliction.setOnClickListener(this);
division.setOnClickListener(this);
root.setOnClickListener(this);
surplus.setOnClickListener(this);
equal.setOnClickListener(this);
delete.setOnClickListener(this);
theFirstView.setOnClickListener(this);
theOptionView.setOnClickListener(this);
theEqualView.setOnClickListener(this);
theSecondView.setOnClickListener(this);
theAnswerView.setOnClickListener(this);
}
第二步就是为每一个按钮添加具体的操作了,首先我先来讲解我的数字按钮。我具体的实现思路是在开始创建三个String对象分别来存储第一个运算数(str1)、运算符(option)和第二个运算数(str2)。当我们点击数字按钮时先判断运算符是否为空,如果为空则说明此时我们要输入的是第一个运算数,否则说明我们要输入的是第二个运算数。在输入时我让运算数=之前的数+按钮输入的数(注意这里我们定义的运算数为String类型),然后再把运算数显示在其想要的TextView当中。所以具体的代码是:
public void onClick(View view) {
switch (view.getId()){
case R.id.zero:
case R.id.one:
case R.id.two:
case R.id.three:
case R.id.four:
case R.id.five:
case R.id.six:
case R.id.seven:
case R.id.eight:
case R.id.nine:
if(option == ""){
str1 = str1+((Button) view).getText().toString();
theFirstView.setText(str1);
}
else{
str2 = str2+((Button) view).getText().toString();
theSecondView.setText(str2);
}
}
break;
......
接着我再来介绍计算符按钮的操作,其实它们内部的操作很简单,就是在点击之后将其运算符号赋值给option以及显示在theOptionView当中:
case R.id.add:
option = "+";
theOptionView.setText("+");
break;
case R.id.substraction:
option = "-";
theOptionView.setText("-");
break;
case R.id.mulitipliction:
option = "×";
theOptionView.setText("×");
break;
case R.id.division:
option = "÷";
theOptionView.setText("÷");
break;
case R.id.surplus:
option = "%";
theOptionView.setText("%");
break;
case R.id.root:
if(str1 == ""){
option = "√";
theOptionView.setText("√");
}
break;
接下来就是介绍显示答案的部分了,我的思路是当点击=之后,会先在theEqualView上面显示出=,然后是在theAnswerView当中显示出我们需要的答案:
case R.id.equal:
theEqualView.setText("=");
answerFlag = 1;
if(option == "+"){
number1 = Double.parseDouble(theFirstView.getText().toString());
number2 = Double.parseDouble(theSecondView.getText().toString());
theAnswerView.setText( (number1+number2)+"");
}
if(option == "-"){
number1 = Double.parseDouble(theFirstView.getText().toString());
number2 = Double.parseDouble(theSecondView.getText().toString());
theAnswerView.setText( (number1-number2)+"");
}
if(option == "×"){
number1 = Double.parseDouble(theFirstView.getText().toString());
number2 = Double.parseDouble(theSecondView.getText().toString());
theAnswerView.setText( (number1*number2)+"");
}
if(option == "÷"){
number1 = Double.parseDouble(theFirstView.getText().toString());
number2 = Double.parseDouble(theSecondView.getText().toString());
if(number2 == 0){
theAnswerView.setText("错误");
}
else{
theAnswerView.setText( (number1/number2)+"");
}
}
if(option == "√"){
number2 = Double.parseDouble(theSecondView.getText().toString());
theAnswerView.setText(Math.sqrt(number2)+"");
}
if(option == "%"){
number1 = Double.parseDouble(theFirstView.getText().toString());
number2 = Double.parseDouble(theSecondView.getText().toString());
theAnswerView.setText(number1%number2+"");
}
break;
然后就是特殊符号的代码实现,手下来介绍一下C,它在计算器里面的意识就是清除掉当前显示的所有数字符号,我这里是使用了一个clear()方法来实现的:
case R.id.clear:
clear();
break;
......
public void clear(){
str1 = "";
str2 = "";
theFirstView.setText("");
theSecondView.setText("");
theOptionView.setText("");
theEqualView.setText("");
theAnswerView.setText("");
option = "";
}
第二个特殊符号是 . 当我们在输入 . 时需要先判断在它之前有没有数字,如果没有数字,则是不能输入的:
case R.id.point:
if(str1 != "" && option == ""){
str1 = str1+((Button) view).getText().toString();
theFirstView.setText(str1);
}
if(option != "" && str2 != ""){
str2 = str2+((Button) view).getText().toString();
theSecondView.setText(str2);
}
else{
//什么都不执行
}
break;
最后一个特殊符号是DEL,它是指消除,我在这里使用的是Java中String类的substring()方法:
case R.id.delete:
if(theAnswerView.getText().toString() == ""){
if((theSecondView.getText().toString())!= ""){
int length = str2.length();
if(length == 1){
theSecondView.setText("");
}
else{
str2 = str2.substring(0,length-1);
theSecondView.setText(str2);
}
break;
}
if((theSecondView.getText().toString()) == "" && (theOptionView.getText().toString()) != ""){
theOptionView.setText("");
break;
}
if((theSecondView.getText().toString()) == "" && (theAnswerView.getText().toString()) == "" && (theFirstView.getText().toString()) != ""){
int length = str1.length();
if(length == 1){
theFirstView.setText("");
}
else{
str1 = str1.substring(0,length-1);
theFirstView.setText(str1);
}
break;
}
}
break;
最后我是简单实现了一下计算器里面的一个小特性,即当我们在得到答案之后如果要再次进行计算,我们可以不必点击C,而是可以直接输入下一次计算的运算数。我这里实现的方法是在点击按钮之前先判断标志位ansFlage是否为0,如果为0,则说明之前还没有进行过运算,如果不为0,则说明之前已经完成了一次运算,需要我们先清空屏幕:
case R.id.zero:
case R.id.one:
case R.id.two:
case R.id.three:
case R.id.four:
case R.id.five:
case R.id.six:
case R.id.seven:
case R.id.eight:
case R.id.nine:
if(answerFlag == 0){
if(option == ""){
str1 = str1+((Button) view).getText().toString();
theFirstView.setText(str1);
}
else{
str2 = str2+((Button) view).getText().toString();
theSecondView.setText(str2);
}
}
if(answerFlag == 1){
clear();
answerFlag = 0;
str1 = str1+((Button) view).getText().toString();
theFirstView.setText(str1);
}
break;