这个简易计算器的实现我是参照慕课网上的视频课程学习的,下面梳理我的开发过程以及DEBUG
在这个项目中实现计算器的第一步骤是对界面UI的设计,UI的设计并不难,一个总的Lnearlayout的布局下orientation设置为vertical垂直分布,然后此布局下再设置1给我Edittext的一个文本框4个Lnearlayout子布局(第4个布局里可以嵌套另外3个Lnearlayout的布局来实现按钮排版)这4个子布局在你的界面上肯定是垂直分布的,因为你的总布局设置vertical。第一个子布局放置4个Button,分别是C、DEL、/和*这4个功能按钮,有一点是让我比较开心的是,之前一直不知道一个按钮或者一个边框的椭圆形边角如何设计出来,系统自带边框正正方方的感觉会有点死板,在Button属性设置中有一个bachganoud设置,我们引用@drawable/btn_bg,这里需要在drawable中新建1个XML的文件,在这个XML文件中设置总标签<shape>,在这个标签里设置的<corners>就是对控件的边角弧度设置,<solid>是对控件的背景填充,<stroke>是对控件的边框以及边框颜色设置。如果引用的是@drawable/btn_selector,那么就需要新建两个XML文件,来实现这个按钮点击前后的一个效果变化。剩下的子布局不再赘述了,情况是类似的,有一点需要注意,需要通过margin这个属性来控制各个子布局的距离,为了界面不要太丑。
(UI界面实现)
UI界面实现后就是对计算器的逻辑实现了,首先在MainActivity中对各个控件进行绑定控件实例化,以及设置监听事件,在这里我是使用实现接口的方式来实现监听事件事件,在控件数量比较多的情况下,这是一个不错的选择。
鼠标点击事件Onclick()里用了一个switch()结构用来识别究竟是点击了哪一个按钮,设置一个变量String str=rt_input.get().toString()来获取文本框里的输入信息,对于case R. id. btn_0到case R.id.btn_point这些按钮,当我们获取到信息后就可以直接输出显示了et_input.setText(str+(Button)v).getText());对于case R.id.btn_plus等加减乘除这些控件,为了和上面的数字按钮区别开来,我们多设置两个空格,下文会用的到,et_input.setText(str+“ ”+(Button)v).getText()+“ ”); 对于case R.id.btn_clean,我们直接设置输出空值就好了et_input.setText(“”);对于case R.id.btn_del,由于需要一个个字符删除,我们添加一个条件if(str!-null&&!str.epual("")){}设置成et_input.setText (str.substring (0, str. length()-1));意思是比原来的文本内容少一个字符显示,嗯,就是这样!最后一个case R.id.equal是我们逻辑实现的关键部门,它就是实现运算的,所以我们需要另外写一个方法getResult()。、
在关键部分getResult()中,首先是也是需要获取文本内容的String exp=rt_input.get().toString(),用于分离操作数和运算符。然后我们按照几种输入情况分别处理:情况一:输入的值是空值或者没有,可以直接返回。情况二:文本内容中没有包含“ ”空格符,这是我们上文提到的空格符,和我们运算符绑定在一起了,这是因为没有检测到空格符,也就是没有输入运算符,只输入的字符,也是直接返回。情况三:输入的两个操作数都不为空(之所以成为“简易计算器”就是因为......它只实现两个操作数之间的四则运算!哈哈),从这里开始我们就要分离操作数和运算符了,采用substring(start,end)的方法分离,注意运算符前后还有空格需要考虑,我们这里将操作数s1和s2强制转换成double 类型。接着就是用if()结构对四则运算分别处理了,该加的加,该减的就减。最后再用一个if()结果,目的是如果两个操作数同时是int类型的,我们再把结果输出强制转换成int 类型。情况四:操作数s1非空,而s2是空值,就直接输出文本框中的内容。情况五:S1是空值,S2不为空值,s2强制转换成double 类型,那么该加减的就加减,该乘除的就输出0,最后的输出也是要用一个if()结构判断一下的,如果是l两个操作数是double,就直接输出,如果是int ,就需要转换一下。情况六:两个操作数都空,直接输出空et_input.setText("").
简易计算器就设计完了!
但是......我的计算器仍然没有能够跑的起来,BUG始终存在呀,我们来DEBUG吧,首先我的程序一运行就出现闪退,根本来不及看见我设计的UI界面,后来看Log日志,它说空指针异常,于是我去检查代码,发现我一个控件btn_equal都没有设置监听事件,DEBUG之后程序可以运行了,但是新出现的问题就是点击“=”按钮,功能无法实现,并且闪退,Log显示是索引溢出,很纳闷,检查很多遍代码发现的错误是et_input.setText(str+“ ”+(Button)v).getText()+“ ”)中,我并没有写上空格:et_input.setText(str+“”+(Button)v) .getText()+“”),OK,这个错误也排除了,程序也不闪退了,但是逻辑运算功能还是没实现,加减乘除通通不行,LOG显示是分离操作数和运算符时出错,我觉得一定是getResult()没有处理好,然后一直检查getResult(),没有发现错误,还把教学视屏重复看了N遍,有点苦逼的,一天之后骂我重新再看整项目时想起来,当初设计UI是,为了数字在按钮中显示的位置比较合理好看,我在每个数值后面都添加了一个空格,Android:text="1 ",就像这样,怪不得操作数和运算符分离是会出现异常,怪自己奇葩挖坑......这个问题也解决了,整个程序就没什么大问题了,还有一点瑕疵:在进行完一次运算后,进行下一次运算,上次的结果还会停留在显示框不会清零,这里我们设置一个boolean值,在case的几种按钮中写上if (clear_flag) {clear_flag = false;str = "";et_input.setText(""); }就可以了!
第一次Bolgs 记录结束!下面把程序源码贴一下:
UI界面:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- tools:context=".MainActivity">
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="50dp"
- android:layout_marginLeft="3dp"
- android:layout_marginRight="3dp">
- <EditText
- android:layout_width="match_parent"
- android:layout_height="60dp"
- android:id="@+id/et_input"
- android:editable="false"
- android:background="@drawable/white_bg"
- android:gravity="center_vertical|right" />
- </LinearLayout>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:orientation="horizontal"
- android:layout_marginTop="20dp">
- <Button
- android:layout_width="60dp"
- android:layout_height="60dp"
- android:id="@+id/btn_clean"
- android:text="C"
- android:textSize="20sp"
- android:layout_marginLeft="10dp"
- android:layout_weight="1"
- android:gravity="bottom|right"
- android:background="@drawable/btn_selector"
- android:paddingBottom="10dp"
- android:paddingRight="10dp"
- />
- <Button
- android:layout_width="60dp"
- android:layout_height="60dp"
- android:id="@+id/btn_del"
- android:text="DEL"
- android:textSize="20sp"
- android:layout_marginLeft="10dp"
- android:layout_weight="1"
- android:gravity="bottom|right"
- android:background="@drawable/btn_selector"
- android:paddingBottom="10dp"
- android:paddingRight="10dp"
- />
- <Button
- android:layout_width="60dp"
- android:layout_height="60dp"
- android:id="@+id/btn_divide"
- android:text="/"
- android:textSize="20sp"
- android:layout_marginLeft="10dp"
- android:layout_weight="1"
- android:gravity="bottom|right"
- android:background="@drawable/btn_selector"
- android:paddingBottom="10dp"
- android:paddingRight="10dp"/>
- <Button
- android:layout_width="60dp"
- android:layout_height="60dp"
- android:id="@+id/btn_multiplay"
- android:text="*"
- android:textSize="20sp"
- android:layout_marginLeft="10dp"
- android:layout_marginRight="10dp"
- android:layout_weight="1"
- android:gravity="bottom|right"
- android:background="@drawable/btn_selector"
- android:paddingBottom="10dp"
- android:paddingRight="10dp"/>
- </LinearLayout>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:orientation="horizontal"
- android:layout_marginTop="10dp">
- <Button
- android:layout_width="60dp"
- android:layout_height="60dp"
- android:id="@+id/btn_7"
- android:text="7"
- android:textSize="20sp"
- android:layout_marginLeft="10dp"
- android:layout_weight="1"
- android:gravity="bottom|right"
- android:background="@drawable/btn_selector"
- android:paddingBottom="10dp"
- android:paddingRight="10dp"/>
- <Button
- android:layout_width="60dp"
- android:layout_height="60dp"
- android:id="@+id/btn_8"
- android:text="8"
- android:textSize="20sp"
- android:layout_marginLeft="10dp"
- android:layout_weight="1"
- android:gravity="bottom|right"
- android:background="@drawable/btn_selector"
- android:paddingBottom="10dp"
- android:paddingRight="10dp"/>
- <Button
- android:layout_width="60dp"
- android:layout_height="60dp"
- android:id="@+id/btn_9"
- android:text="9"
- android:textSize="20sp"
- android:layout_marginLeft="10dp"
- android:layout_weight="1"
- android:gravity="bottom|right"
- android:background="@drawable/btn_selector"
- android:paddingBottom="10dp"
- android:paddingRight="10dp"/>
- <Button
- android:layout_width="60dp"
- android:layout_height="60dp"
- android:id="@+id/btn_minus"
- android:text="-"
- android:textSize="20sp"
- android:layout_marginLeft="10dp"
- android:layout_marginRight="10dp"
- android:layout_weight="1"
- android:gravity="bottom|right"
- android:background="@drawable/btn_selector"
- android:paddingBottom="10dp"
- android:paddingRight="10dp"/>
- </LinearLayout>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:orientation="horizontal"
- android:layout_marginTop="10dp">
- <Button
- android:layout_width="60dp"
- android:layout_height="60dp"
- android:id="@+id/btn_4"
- android:text="4"
- android:textSize="20sp"
- android:layout_marginLeft="10dp"
- android:layout_weight="1"
- android:gravity="bottom|right"
- android:background="@drawable/btn_selector"
- android:paddingBottom="10dp"
- android:paddingRight="10dp"/>
- <Button
- android:layout_width="60dp"
- android:layout_height="60dp"
- android:id="@+id/btn_5"
- android:text="5"
- android:textSize="20sp"
- android:layout_marginLeft="10dp"
- android:layout_weight="1"
- android:gravity="bottom|right"
- android:background="@drawable/btn_selector"
- android:paddingBottom="10dp"
- android:paddingRight="10dp"/>
- <Button
- android:layout_width="60dp"
- android:layout_height="60dp"
- android:id="@+id/btn_6"
- android:text="6"
- android:textSize="20sp"
- android:layout_marginLeft="10dp"
- android:layout_weight="1"
- android:gravity="bottom|right"
- android:background="@drawable/btn_selector"
- android:paddingBottom="10dp"
- android:paddingRight="10dp"/>
- <Button
- android:layout_width="60dp"
- android:layout_height="60dp"
- android:id="@+id/btn_plus"
- android:text="+"
- android:textSize="20sp"
- android:layout_marginLeft="10dp"
- android:layout_marginRight="10dp"
- android:layout_weight="1"
- android:gravity="bottom|right"
- android:background="@drawable/btn_selector"
- android:paddingBottom="10dp"
- android:paddingRight="10dp"/>
- </LinearLayout>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:layout_marginTop="10dp">
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:layout_weight="3"
- >
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- >
- <Button
- android:layout_width="60dp"
- android:layout_height="60dp"
- android:id="@+id/btn_1"
- android:text="1"
- android:textSize="20sp"
- android:layout_marginLeft="10dp"
- android:layout_weight="1"
- android:gravity="bottom|right"
- android:background="@drawable/btn_selector"
- android:paddingBottom="10dp"
- android:paddingRight="10dp"/>
- <Button
- android:layout_width="60dp"
- android:layout_height="60dp"
- android:id="@+id/btn_2"
- android:text="2"
- android:textSize="20sp"
- android:layout_marginLeft="10dp"
- android:layout_weight="1"
- android:gravity="bottom|right"
- android:background="@drawable/btn_selector"
- android:paddingBottom="10dp"
- android:paddingRight="10dp"/>
- <Button
- android:layout_width="60dp"
- android:layout_height="60dp"
- android:id="@+id/btn_3"
- android:text="3"
- android:textSize="20sp"
- android:layout_marginLeft="10dp"
- android:layout_weight="1"
- android:gravity="bottom|right"
- android:background="@drawable/btn_selector"
- android:paddingBottom="10dp"
- android:paddingRight="10dp"/>
- </LinearLayout>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="10dp">
- <Button
- android:layout_width="60dp"
- android:layout_height="60dp"
- android:id="@+id/btn_0"
- android:text="0"
- android:textSize="20sp"
- android:layout_marginLeft="10dp"
- android:layout_weight="1"
- android:gravity="bottom|right"
- android:background="@drawable/btn_selector"
- android:paddingBottom="10dp"
- android:paddingRight="10dp"/>
- <Button
- android:layout_width="60dp"
- android:layout_height="60dp"
- android:id="@+id/btn_point"
- android:text="."
- android:textSize="20sp"
- android:layout_marginLeft="10dp"
- android:layout_weight="1"
- android:gravity="bottom|right"
- android:background="@drawable/btn_selector"
- android:paddingBottom="10dp"
- android:paddingRight="10dp"/>
- </LinearLayout>
- </LinearLayout>
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- >
- <Button
- android:layout_width="60dp"
- android:layout_height="130dp"
- android:id="@+id/btn_equal"
- android:text="="
- android:textSize="20sp"
- android:layout_marginLeft="10dp"
- android:layout_marginRight="10dp"
- android:layout_weight="1"
- android:gravity="bottom|right"
- android:background="@drawable/orange_selector"
- android:paddingBottom="10dp"
- android:paddingRight="10dp"/>
- </LinearLayout>
- </LinearLayout>
- </LinearLayout>
- <span style="font-size:18px;">//按钮点击后的样式:</span>
- <?xml version="1.0" encoding="utf-8"?>
- <shape xmlns:android="http://schemas.android.com/apk/res/android">
- <corners android:radius="5dp"/>
- <solid
- android:color="@android:color/darker_gray"/>
- <stroke
- android:width="1dp"
- android:color="@android:color/black"/>
- </shape>
- <?xml version="1.0" encoding="utf-8"?>
- <shape xmlns:android="http://schemas.android.com/apk/res/android">
- <corners android:radius="5dp"/>
- <!--<gradient-->
- <!--android:startColor="@color/colorAccent"-->
- <!--android:endColor="@color/colorAccent"/>-->
- <solid
- android:color="@android:color/white"/>
- <stroke
- android:width="1dp"
- android:color="@android:color/black"/>
- </shape>
//按钮点击前后的变化实现
- <?xml version="1.0" encoding="utf-8"?>
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:drawable="@drawable/gray_btn" android:state_pressed="true"/>
- <item android:drawable="@drawable/white_bg"/>
- </selector>
- package com.example.boss.calculator;
- import android.os.Bundle;
- import android.support.v7.app.AppCompatActivity;
- import android.view.View;
- import android.widget.Button;
- import android.widget.EditText;
- public class MainActivity extends AppCompatActivity implements View.OnClickListener {
- Button btn_0, btn_1, btn_2, btn_3, btn_4, btn_5,
- btn_6, btn_7, btn_8, btn_9, btn_equal,
- btn_point, btn_clean, btn_del, btn_plus,
- btn_minus, btn_multiply, btn_divide;
- EditText et_input;
- boolean clear_flag;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- btn_0 = (Button) findViewById(R.id.btn_0);
- btn_1 = (Button) findViewById(R.id.btn_1);
- btn_2 = (Button) findViewById(R.id.btn_2);
- btn_3 = (Button) findViewById(R.id.btn_3);
- btn_4 = (Button) findViewById(R.id.btn_4);
- btn_5 = (Button) findViewById(R.id.btn_5);
- btn_6 = (Button) findViewById(R.id.btn_6);
- btn_7 = (Button) findViewById(R.id.btn_7);
- btn_8 = (Button) findViewById(R.id.btn_8);
- btn_9 = (Button) findViewById(R.id.btn_9);
- btn_clean = (Button) findViewById(R.id.btn_clean);
- btn_equal = (Button) findViewById(R.id.btn_equal);
- btn_minus = (Button) findViewById(R.id.btn_minus);
- btn_multiply = (Button) findViewById(R.id.btn_multiplay);
- btn_plus = (Button) findViewById(R.id.btn_plus);
- btn_point = (Button) findViewById(R.id.btn_point);
- btn_del = (Button) findViewById(R.id.btn_del);
- btn_divide = (Button) findViewById(R.id.btn_divide);
- et_input = (EditText) findViewById(R.id.et_input);
- btn_0.setOnClickListener(this);
- btn_1.setOnClickListener(this);
- btn_2.setOnClickListener(this);
- btn_3.setOnClickListener(this);
- btn_4.setOnClickListener(this);
- btn_5.setOnClickListener(this);
- btn_6.setOnClickListener(this);
- btn_7.setOnClickListener(this);
- btn_8.setOnClickListener(this);
- btn_9.setOnClickListener(this);
- btn_equal.setOnClickListener(this);
- btn_minus.setOnClickListener(this);
- btn_multiply.setOnClickListener(this);
- btn_divide.setOnClickListener(this);
- btn_del.setOnClickListener(this);
- btn_point.setOnClickListener(this);
- btn_plus.setOnClickListener(this);
- btn_clean.setOnClickListener(this);
- et_input.setOnClickListener(this);
- }
- @Override
- public void onClick(View v) {
- String str = et_input.getText().toString();
- switch (v.getId()) {
- case R.id.btn_0:
- case R.id.btn_1:
- case R.id.btn_2:
- case R.id.btn_3:
- case R.id.btn_4:
- case R.id.btn_5:
- case R.id.btn_6:
- case R.id.btn_7:
- case R.id.btn_8:
- case R.id.btn_9:
- case R.id.btn_point:
- if (clear_flag) {
- clear_flag = false;
- str = "";
- et_input.setText("");
- }
- et_input.setText(str + ((Button) v).getText());
- break;
- case R.id.btn_plus:
- case R.id.btn_minus:
- case R.id.btn_multiplay:
- case R.id.btn_divide:
- if (clear_flag) {
- clear_flag = false;
- str = "";
- et_input.setText("");
- }
- et_input.setText(str + " " + ((Button) v).getText() + " ");
- break;
- case R.id.btn_clean:
- clear_flag = false;
- et_input.setText("");
- break;
- case R.id.btn_del:
- if (clear_flag) {
- clear_flag = false;
- et_input.setText("");
- } else if (str != null && !str.equals("")) {
- et_input.setText(str.substring(0, str.length() - 1));
- }
- case R.id.btn_equal:
- getResult();
- break;
- default:
- break;
- }
- }
- private void getResult() {
- String exp = et_input.getText().toString();
- if(exp==null||exp.equals("")){
- return;
- }
- if(!exp.contains(" ")){
- return;
- }
- if(clear_flag){
- clear_flag=false;
- return ;
- }
- clear_flag = true;
- double result = 0;
- String s1 = exp.substring(0, exp.indexOf(" "));
- String op = exp.substring(exp.indexOf(" ") + 1, exp.indexOf(" ") + 2);
- String s2 = exp.substring(exp.indexOf(" ") + 3);
- if (!s1.equals("") && !s2.equals("")) {
- double d1 = Double.parseDouble(s1);
- double d2 = Double.parseDouble(s2);
- if (op.equals("+")) {
- result = d1 + d2;
- } else if (op.equals("-")) {
- result = d1 - d2;
- } else if (op.equals("*")) {
- result = d1 * d2;
- } else if (op.equals("/")) {
- if (d2 == 0) {
- result = 0;
- } else {
- result = d1 / d2;
- }
- }
- if (!s1.contains(".") && !s2.contains(".") && !op.equals("/")) {
- int r = (int) result;
- et_input.setText(r + "");
- } else {
- et_input.setText(result + "");
- }
- }
- else if(!s1.equals("")&&s2.equals("")){
- et_input.setText(exp);
- }
- else if(s1.equals("")&&!s2.equals("")){
- double d2=Double.parseDouble(s2);
- if(op.equals("+")){
- result=0+d2;
- }else if(op.equals("-")){
- result=0-d2;
- }else if(op.equals("*")){
- result=0;
- }else if(op.equals("/")){
- result = 0;
- }
- if(!s2.contains(".")){
- int r=(int) result;
- et_input.setText(r+" ");
- } else{
- et_input.setText(result+" ");
- }
- }else{
- et_input.setText("");
- }
- }
- }