zoukankan      html  css  js  c++  java
  • Android简易计算器

    本次APP的源码已上传到我的GitHub:https://github.com/zdm-code/Android-learning/tree/master/android_learning/app

    经过长达两天的Android的学习,觉得已经可以做一些简单的小APP练练手。本次就做了一个简易计算器,下面简单记录一下开发过程。

    本次开发运用了前几次关于Android博文里的一些内容。主要使用了几个基本的控件,通过drawable设计控件样式,通过线性布局将所有控件串联起来。

    计算器是人们生活中最常用的工具之一,无论在电脑上还是手机上,都少不了计算器的身影。原本以为计算器的开发还是蛮简单的,结果在前端写好之后,一进入activity的java代码编写就发现了很多细节问题。如:用户非法数据的输入判断(例如00012,1.23.45,1+*3等等)以及用户体验等,通过简单的点击打印的方式会很容易导致数据不合法,因此后台需要判断并控制用户的输入数据。

    先来简单对比一下手机自带的计算器和自己开发的计算器

              

    如图所见,样子还是比较相似的(其实是照着手机上自带的样子开发的)。我的计算器有三部分组成:标题,显示区(TextView),按键区(Button),它能实现基本的加减乘除运算功能(包括连续表达式的求值),体验感已和手机自带计算器基本一致。

    这里不再给出布局代码,仅附上activity的java代码

      1 package com.example.animator.android_learning;
      2 
      3 import android.content.Context;
      4 import android.support.v7.app.ActionBarActivity;
      5 import android.os.Bundle;
      6 import android.util.DisplayMetrics;
      7 import android.view.View;
      8 import android.view.WindowManager;
      9 import android.widget.Button;
     10 import android.widget.TextView;
     11 import android.widget.Toast;
     12 
     13 import com.example.animator.utils.Calculator;
     14 import com.example.animator.utils.IsSecondNumZero;
     15 
     16 public class MainActivity extends ActionBarActivity implements View.OnClickListener {
     17 
     18     TextView textView;
     19     Button btn_1;
     20     Button btn_2;
     21     Button btn_3;
     22     Button btn_4;
     23     Button btn_5;
     24     Button btn_6;
     25     Button btn_7;
     26     Button btn_8;
     27     Button btn_9;
     28     Button btn_10;
     29     Button btn_11;
     30     Button btn_12;
     31     Button btn_13;
     32     Button btn_14;
     33     Button btn_15;
     34     Button btn_16;
     35     Button btn_17;
     36     Button btn_18;
     37     Button btn_19;
     38 
     39     @Override
     40     protected void onCreate(Bundle savedInstanceState) {
     41         super.onCreate(savedInstanceState);
     42         setContentView(R.layout.activity_main);
     43         textView= (TextView) findViewById(R.id.tv_show);
     44         btn_1= (Button) findViewById(R.id.btn_1);
     45         btn_2= (Button) findViewById(R.id.btn_2);
     46         btn_3= (Button) findViewById(R.id.btn_3);
     47         btn_4= (Button) findViewById(R.id.btn_4);
     48         btn_5= (Button) findViewById(R.id.btn_5);
     49         btn_6= (Button) findViewById(R.id.btn_6);
     50         btn_7= (Button) findViewById(R.id.btn_7);
     51         btn_8= (Button) findViewById(R.id.btn_8);
     52         btn_9= (Button) findViewById(R.id.btn_9);
     53         btn_10= (Button) findViewById(R.id.btn_10);
     54         btn_11= (Button) findViewById(R.id.btn_11);
     55         btn_12= (Button) findViewById(R.id.btn_12);
     56         btn_13= (Button) findViewById(R.id.btn_13);
     57         btn_14= (Button) findViewById(R.id.btn_14);
     58         btn_15= (Button) findViewById(R.id.btn_15);
     59         btn_16= (Button) findViewById(R.id.btn_16);
     60         btn_17= (Button) findViewById(R.id.btn_17);
     61         btn_18= (Button) findViewById(R.id.btn_18);
     62         btn_19= (Button) findViewById(R.id.btn_19);
     63 
     64         btn_1.setOnClickListener(this);
     65         btn_2.setOnClickListener(this);
     66         btn_3.setOnClickListener(this);
     67         btn_4.setOnClickListener(this);
     68         btn_5.setOnClickListener(this);
     69         btn_6.setOnClickListener(this);
     70         btn_7.setOnClickListener(this);
     71         btn_8.setOnClickListener(this);
     72         btn_9.setOnClickListener(this);
     73         btn_10.setOnClickListener(this);
     74         btn_11.setOnClickListener(this);
     75         btn_12.setOnClickListener(this);
     76         btn_13.setOnClickListener(this);
     77         btn_14.setOnClickListener(this);
     78         btn_15.setOnClickListener(this);
     79         btn_16.setOnClickListener(this);
     80         btn_17.setOnClickListener(this);
     81         btn_18.setOnClickListener(this);
     82         btn_19.setOnClickListener(this);
     83 
     84 
     85 
     86     }
     87 
     88 
     89     //根据手机的分辨率从dp单位转换成px单位
     90     public static int dip2px(Context context,float dpValue){
     91         //获取当前手机的像素密度
     92         final float scale=context.getResources().getDisplayMetrics().density;
     93         return (int)(dpValue*scale+0.5f); //四舍五入取整
     94     }
     95 
     96     //根据手机的分辨率从px单位转换成dp单位
     97     public static int px2dip(Context context,float pxValue){
     98         //获取当前手机的像素密度
     99         final float scale=context.getResources().getDisplayMetrics().density;
    100         return (int)(pxValue/scale+0.5f); //四舍五入取整
    101     }
    102 
    103     public static int getScreenWidth(Context context){
    104         //从系统服务中获取窗口管理器
    105         WindowManager windowManager=(WindowManager)context.getSystemService(context.WINDOW_SERVICE);
    106         DisplayMetrics displayMetrics=new DisplayMetrics();
    107         //从默认显示器中获取显示参数保存到displayMetrics对象中
    108         windowManager.getDefaultDisplay().getMetrics(displayMetrics);
    109         return displayMetrics.widthPixels; //返回屏幕的宽度数值
    110     }
    111 
    112     public static int getScreenHeight(Context context){
    113         //从系统服务中获取窗口管理器
    114         WindowManager windowManager=(WindowManager)context.getSystemService(context.WINDOW_SERVICE);
    115         DisplayMetrics displayMetrics=new DisplayMetrics();
    116         //从默认显示器中获取显示参数保存到displayMetrics对象中
    117         windowManager.getDefaultDisplay().getMetrics(displayMetrics);
    118         return displayMetrics.heightPixels; //返回屏幕的高度数值
    119     }
    120 
    121     public static float getScreenDensity(Context context){
    122         //从系统服务中获取窗口管理器
    123         WindowManager windowManager=(WindowManager)context.getSystemService(context.WINDOW_SERVICE);
    124         DisplayMetrics displayMetrics=new DisplayMetrics();
    125         //从默认显示器中获取显示参数保存到displayMetrics对象中
    126         windowManager.getDefaultDisplay().getMetrics(displayMetrics);
    127         return displayMetrics.density; //返回屏幕的高度数值
    128     }
    129 
    130     @Override
    131     public void onClick(View view) {
    132         String text=textView.getText().toString();
    133         String[] number=text.split("[+|-|*|/|=]");
    134         String lastnumber="";
    135         if(number.length>0)
    136             lastnumber=number[number.length-1];
    137         switch (view.getId()){
    138             case R.id.btn_1:
    139             case R.id.btn_16://删除数字键,计算完毕后点击全部清除,表达式书写中则去除最后一个字符
    140                 if(text.contains("=")){
    141                     textView.setText("");
    142                 }else {
    143                     if (text.length() > 0)
    144                         textView.setText(text.substring(0, text.length() - 1));
    145                 }
    146                 break;
    147             case R.id.btn_2:
    148                 //除号键,判定是否计算完成,若完成则取结果继续运算
    149                 if(text.length()>0) {
    150                     if(text.contains("=")){
    151                         textView.setText(lastnumber+"/");
    152                     }
    153                     //判断前面字符是否为符号,若是,则将其改为当前输入符号(注意两符号不能同时出现)
    154                     else {
    155                         if (text.substring(text.length() - 1).equals("+") == false && text.substring(text.length() - 1).equals("-") == false && text.substring(text.length() - 1).equals("*") == false &&
    156                                 text.substring(text.length() - 1).equals("/") == false && text.substring(text.length() - 1).equals(".") == false)
    157                             textView.setText(text + "/");
    158                         else if (text.substring(text.length() - 1).equals("+") == true || text.substring(text.length() - 1).equals("-") == true || text.substring(text.length() - 1).equals("*") == true ||
    159                                 text.substring(text.length() - 1).equals("/") == true)
    160                             textView.setText(text.substring(0, text.length() - 1) + "/");
    161                     }
    162                 }
    163                 break;
    164             case R.id.btn_3:
    165                 //乘号键,用法大致同除号
    166                 if(text.length()>0) {
    167                     if(text.contains("=")){
    168                         textView.setText(lastnumber+"*");
    169                     }
    170                     else {
    171                         if (text.substring(text.length() - 1).equals("+") == false && text.substring(text.length() - 1).equals("-") == false && text.substring(text.length() - 1).equals("*") == false &&
    172                                 text.substring(text.length() - 1).equals("/") == false && text.substring(text.length() - 1).equals(".") == false)
    173                             textView.setText(text + "*");
    174                         else if (text.substring(text.length() - 1).equals("+") == true || text.substring(text.length() - 1).equals("-") == true || text.substring(text.length() - 1).equals("*") == true ||
    175                                 text.substring(text.length() - 1).equals("/") == true)
    176                             textView.setText(text.substring(0, text.length() - 1) + "*");
    177                     }
    178                 }
    179                 break;
    180             case R.id.btn_4:
    181                 //全部清除键
    182                 textView.setText("");
    183                 break;
    184             case R.id.btn_5:
    185                 //数字7,判断组合数字首位是否为0,若是,则将其置为7,下面数字用法类似
    186                 if(text.contains("="))
    187                 {
    188                     textView.setText("7");
    189                 }else if((text.length()>2&&text.charAt(text.length()-1)=='0'&&isOperation(text.charAt(text.length()-2)))||(text.length()==1&&text.charAt(0)=='0'))
    190                 {
    191                     textView.setText(text.substring(0, text.length() - 1) + "7");
    192                 }else
    193                     textView.setText(text+"7");
    194                 break;
    195             case R.id.btn_6:
    196                 if(text.contains("="))
    197                 {
    198                     textView.setText("8");
    199                 }else if((text.length()>2&&text.charAt(text.length()-1)=='0'&&isOperation(text.charAt(text.length()-2)))||(text.length()==1&&text.charAt(0)=='0'))
    200                 {
    201                     textView.setText(text.substring(0, text.length() - 1) + "8");
    202                 }else
    203                     textView.setText(text+"8");
    204                 break;
    205             case R.id.btn_7:
    206                 if(text.contains("="))
    207                 {
    208                     textView.setText("9");
    209                 }else if((text.length()>2&&text.charAt(text.length()-1)=='0'&&isOperation(text.charAt(text.length()-2)))||(text.length()==1&&text.charAt(0)=='0'))
    210                 {
    211                     textView.setText(text.substring(0, text.length() - 1) + "9");
    212                 }else
    213                     textView.setText(text+"9");
    214                 break;
    215             case R.id.btn_8:
    216                 if(text.length()>0) {
    217                     if(text.contains("=")){
    218                         textView.setText(lastnumber+"+");
    219                     }
    220                     else {
    221                         if (text.substring(text.length() - 1).equals("+") == false && text.substring(text.length() - 1).equals("-") == false && text.substring(text.length() - 1).equals("*") == false &&
    222                                 text.substring(text.length() - 1).equals("/") == false && text.substring(text.length() - 1).equals(".") == false)
    223                             textView.setText(text + "+");
    224                         else if (text.substring(text.length() - 1).equals("+") == true || text.substring(text.length() - 1).equals("-") == true || text.substring(text.length() - 1).equals("*") == true ||
    225                                 text.substring(text.length() - 1).equals("/") == true)
    226                             textView.setText(text.substring(0, text.length() - 1) + "+");
    227                     }
    228                 }
    229                 break;
    230             case R.id.btn_9:
    231                 if(text.contains("="))
    232                 {
    233                     textView.setText("4");
    234                 }else if((text.length()>2&&text.charAt(text.length()-1)=='0'&&isOperation(text.charAt(text.length()-2)))||(text.length()==1&&text.charAt(0)=='0'))
    235                 {
    236                     textView.setText(text.substring(0, text.length() - 1) + "4");
    237                 }else
    238                     textView.setText(text+"4");
    239                 break;
    240             case R.id.btn_10:
    241                 if(text.contains("="))
    242                 {
    243                     textView.setText("5");
    244                 }else if((text.length()>2&&text.charAt(text.length()-1)=='0'&&isOperation(text.charAt(text.length()-2)))||(text.length()==1&&text.charAt(0)=='0'))
    245                 {
    246                     textView.setText(text.substring(0, text.length() - 1) + "5");
    247                 }else
    248                     textView.setText(text+"5");
    249                 break;
    250             case R.id.btn_11:
    251                 if(text.contains("="))
    252                 {
    253                     textView.setText("6");
    254                 }else if((text.length()>2&&text.charAt(text.length()-1)=='0'&&isOperation(text.charAt(text.length()-2)))||(text.length()==1&&text.charAt(0)=='0'))
    255                 {
    256                     textView.setText(text.substring(0, text.length() - 1) + "6");
    257                 }else
    258                     textView.setText(text+"6");
    259                 break;
    260             case R.id.btn_12:
    261                 if(text.length()>0) {
    262                     if(text.contains("=")){
    263                         textView.setText(lastnumber+"-");
    264                     }
    265                     else {
    266                         if (text.substring(text.length() - 1).equals("+") == false && text.substring(text.length() - 1).equals("-") == false && text.substring(text.length() - 1).equals("*") == false &&
    267                                 text.substring(text.length() - 1).equals("/") == false && text.substring(text.length() - 1).equals(".") == false)
    268                             textView.setText(text + "-");
    269                         else if (text.substring(text.length() - 1).equals("+") == true || text.substring(text.length() - 1).equals("-") == true || text.substring(text.length() - 1).equals("*") == true ||
    270                                 text.substring(text.length() - 1).equals("/") == true)
    271                             textView.setText(text.substring(0, text.length() - 1) + "-");
    272                     }
    273                 }
    274                 break;
    275             case R.id.btn_13:
    276                 if(text.contains("="))
    277                 {
    278                     textView.setText("1");
    279                 }else if((text.length()>2&&text.charAt(text.length()-1)=='0'&&isOperation(text.charAt(text.length()-2)))||(text.length()==1&&text.charAt(0)=='0'))
    280                 {
    281                     textView.setText(text.substring(0, text.length() - 1) + "1");
    282                 }else
    283                     textView.setText(text+"1");
    284                 break;
    285             case R.id.btn_14:
    286                 if(text.contains("="))
    287                 {
    288                     textView.setText("2");
    289                 }else if((text.length()>2&&text.charAt(text.length()-1)=='0'&&isOperation(text.charAt(text.length()-2)))||(text.length()==1&&text.charAt(0)=='0'))
    290                 {
    291                     textView.setText(text.substring(0, text.length() - 1) + "2");
    292                 }else
    293                     textView.setText(text+"2");
    294                 break;
    295             case R.id.btn_15:
    296                 if(text.contains("="))
    297                 {
    298                     textView.setText("3");
    299                 }else if((text.length()>2&&text.charAt(text.length()-1)=='0'&&isOperation(text.charAt(text.length()-2)))||(text.length()==1&&text.charAt(0)=='0'))
    300                 {
    301                     textView.setText(text.substring(0, text.length() - 1) + "3");
    302                 }else
    303                     textView.setText(text+"3");
    304                 break;
    305             case R.id.btn_17:
    306                 if(text.contains("="))
    307                 {
    308                     textView.setText("0");
    309                 }else {
    310                     //判断当前数字是否仅为“0”,即不包含小数点,数字头不能出现多个0
    311                     if (lastnumber.equals("0") == false)
    312                         textView.setText(text + "0");
    313                 }
    314                 break;
    315             case R.id.btn_18:
    316                 //小数点,判断是否计算完成,若是,则打印0.
    317                 if(text.contains("="))
    318                 {
    319                     textView.setText("0.");
    320                 }else if(lastnumber.contains(".")==false){//保证同一数字里只有一个小数点
    321                     if (text.length() > 0) {
    322                         if (text.substring(text.length() - 1).equals("+") == false && text.substring(text.length() - 1).equals("-") == false && text.substring(text.length() - 1).equals("*") == false &&
    323                                 text.substring(text.length() - 1).equals("/") == false && text.substring(text.length() - 1).equals(".") == false)
    324                             textView.setText(text + ".");
    325                         else if (text.substring(text.length() - 1).equals("+") == true || text.substring(text.length() - 1).equals("-") == true || text.substring(text.length() - 1).equals("*") == true ||
    326                                 text.substring(text.length() - 1).equals("/") == true)
    327                             textView.setText(text + "0.");
    328                     } else {
    329                         textView.setText("0.");
    330                     }
    331                 }
    332                 break;
    333             case R.id.btn_19:
    334                 if(text.contains("=")==false) {
    335                     if (IsSecondNumZero.isAvailable(text + "=")) {//判断除法是除数为0的情况
    336                         Toast.makeText(MainActivity.this, "除数不能为0", Toast.LENGTH_LONG).show();
    337                     } else {//通过栈进行结果运算
    338                         Calculator calculator = new Calculator();
    339                         String result = calculator.convertDoubleToString(calculator.calculate(text));
    340                         textView.setText(text + "=" + result);
    341                     }
    342                 }
    343                 break;
    344         }
    345     }
    346 
    347     public boolean isOperation(char c){
    348         return c=='+'||c=='-'||c=='*'||c=='/';
    349     }
    350 }

    其中有一些冗余的代码,读者可自行缩减。

    APP中通过栈来进行表达式求值的工具类借鉴如下博客:https://blog.csdn.net/qq_40378034/article/details/100112130?utm_source=app,并对博客中首数字负数报错的部分进行了修改。

    下面再附上除法判断除数为0的代码(由于是最后求值,表达式中可能有多个除号,所以需要遍历所有除号)

     1 package com.example.animator.utils;
     2 
     3 import android.util.Log;
     4 
     5 import java.math.BigDecimal;
     6 import java.util.ArrayList;
     7 
     8 /**
     9  * Created by animator on 2020/1/14.
    10  */
    11 public class IsSecondNumZero {
    12     public static boolean isAvailable(String str){
    13         ArrayList<Integer> divlist=new ArrayList<>();//储存除号索引
    14         ArrayList<Integer> alllist=new ArrayList<>();//储存所有运算符索引
    15 
    16         for(int i=0;i<str.length();i++)
    17         {
    18             if(str.charAt(i)=='/')
    19             {
    20                 divlist.add(i);
    21                 alllist.add(i);
    22             }
    23             else if(str.charAt(i)=='+'||str.charAt(i)=='-'||str.charAt(i)=='*'||str.charAt(i)=='=')
    24             {
    25                 alllist.add(i);
    26             }
    27         }
    28         Log.v("divsize",divlist.size()+"");
    29         Log.v("allsize",alllist.size()+"");
    30         for(int i=0;i<divlist.size();i++){
    31             String string=str.substring(divlist.get(i)+1,alllist.get(alllist.indexOf(divlist.get(i)) + 1));
    32             BigDecimal num = new BigDecimal(string);
    33             if(num.compareTo(new BigDecimal("0"))==0)
    34                 return true;
    35         }
    36         return false;
    37 
    38     }
    39 }
  • 相关阅读:
    iOS 各种编译错误汇总
    Reveal查看任意app的高级技巧
    PCH in Xcode 6
    iOS开发之工具篇-20个可以帮你简化移动app开发流程的工具
    UICollectionViewController xcode6.1 自定义Cell
    Xcode6.1 Prefix.pch添加方式
    最近开始研究php的缓存技术,来个系统自带的OPcache
    今天练手了下mysqlbinlog,标记下
    写了个数组多个数组合并返回的是不重复的数组
    ngnix配置thinkphp5隐藏index.php的方法亲测有效
  • 原文地址:https://www.cnblogs.com/zdm-code/p/12193719.html
Copyright © 2011-2022 走看看