Android小项目——计算器

项目背景

拿来练手的小项目,一开始觉得毛毛雨啦~~~真正动起手来却发现有很多细节值得深究,先po上开发环境。

  • 操作系统:win10
  • JDK:1.8
  • SDK:
  • 开发工具:Android Studio 2.2

布局

关于计算器的布局向来有多种实现方法,比较主流的是LinearLayout、GridLayout 和 TableLayout。

LinearLayout

LinearLayout是最原始的实现方法,布局效果和层级结构如下:

这里写图片描述

这里为Button equal设置了较大margin是因为一旦为按钮设置了背景色就会失去按钮原先的圆角,排列会比较拥挤。实现布局的要点有三个:

  • 可以通过LinearLayout的层级嵌套实现跨行
  • 通过父组件的 android:weightSum 和 子组件的 android:layout_weight 属性实现跨列
  • 使用 android:layout_weight 属性时,如果是对竖直方向分割,组件的 android:layout_width 属性值设为0dp ,水平方向同理,这样可以均匀分配屏幕空间以自适应屏幕尺寸,且每一格的大小不受组件自身的大小影响

缺点

代码比较复杂,嵌套太多有时会有性能问题

GridLayout

Gridlayout是Android 4.0之后出现的,通过行和列将空间划分成若干单元格,每个单元格的最小尺寸是其中组件自身的尺寸,且会与同一行/列里最长的单元格自动对齐。这样的特性使其不能很好地适应不同屏幕的分辨率,会出现不能均匀地占满空间或者超出屏幕边界的问题。

在网上看到GridLayout 和 LinearLayout使用的API差不多,然后我就想用LinearLayout的方式来解决屏幕适配问题,即将子控件的宽高设为0dp,然后通过android:layout_columWeight 和 android:layout_rowWeight 属性来分配屏幕空间。效果如下,但是Android 7.0以前的版本并不支持这种写法。

这里写图片描述

小伙伴们如果有gridlayout优化的解决方案,还请不吝赐教,拜托拜托~~~

TableLayout

TableLayout是继承自LinearLayout的,所以也可以通过android:WeightSum属性和android:layout_weight 属性来解决屏幕适配问题,但与LinearLayout不同的是TableLayout 的子组件不用将宽高设为0dp,因为TableLayout子组件的默认宽高是wrap_content且无法更改,这一点也简化了代码。

缺点:只能用android:layout_span 属性跨列,无法实现跨行

综上,基于实现效果的考虑,最后我选择了LinearLayout来布局

逻辑实现

将输入拼接成字符串

  1. 定义一个String全局变量 last 来存放输入的字符串,为 0~9 和 clear、delete、point 按钮添加 buildNumber 方法,用来处理输入的拼接;
  2. clear 是清除键,按下此键后,程序里所有与数据及操作有关的全局变量都应重置为0或“0”
  3. delete是清除键,String.subString(int start,int end) 方法可以用来截取字符串,我们这里从0截取到 length()-1 就好了。另外,last只剩下一个字符时继续delete要将last置为“0”,否则last的值会为null
  4. 处理0~9的时候只要判断last是否为“0”,如果是,那就覆盖掉,如果不是,就直接在后边拼接。
  5. point的处理不仅要注意4中的问题,还有就是判断last里是否已经含有“.“,只有在不含有”.“的last后边才可以拼接
  6. 因为0~9的处理逻辑是相似的,所以可以考虑合并在一起,我是用把接收到的View类型变量向下强制转换成Button类型来获取要拼接的数字

哒哒哒哒,po代码:

 public void buildNumber(View v){
        switch(v.getId()){
            case R.id.clear:
                factorFirst=new Double(0.0);
                factorSecond=new Double(0.0);
                factor=new Double(0.0);
                flag=0;
                last="0";
                break;
            case R.id.delete:
                if(last.length()==1)
                    last="0";
                else
                    last=last.substring(0,last.length()-1);
                break;
            case R.id.number0:case R.id.number1:case R.id.number2:case R.id.number3:
            case R.id.number4:case R.id.number5:case R.id.number6:case R.id.number7:
            case R.id.number8:case R.id.number9:
                if(last.equals("0"))
                    last=((Button)v).getText().toString();
                else
                    last+=((Button)v).getText().toString();
                break;
            case R.id.point:
                if(last.indexOf(".")<0)
                    last+=".";
                break;
        }
        mResultText.setText(last);
    }

操作符响应

  1. 定义Double类型的全局变量factor、factorFirst、factorSecond,分别用来存放计算结果、第一个操作数和第二个操作数,之所以使用double的包装类是因为将来factor要作为setText()的参数传进去,必须将数值转化成String类型
  2. 为+、-、×、÷四个Button添加calculate方法,用来处理操作符的响应
  3. 使用包装类的Double.pareDouble(String), 将输入转化为第一个操作数,清空输入历史
  4. 定义一个Int全局变量来保存时那种操作符

代码如下:

public void calculate(View v) {
        factorFirst = Double.parseDouble(last);
        last = "0";
        switch (v.getId()) {
            case R.id.add:
                flag = 1;
                break;
            case R.id.minus:
                flag = 2;
                break;
            case R.id.multiply:
                flag = 3;
                break;
            case R.id.divide:
                flag = 4;
                break;
        }
    }

计算结果——等号的响应

  1. 将新的输入结果转化成数值存储在factorSecond变量里,清零输入记录
  2. 根据flag的数值进行运算得出结果,注意,处理除法运算时要判断factorSecond的值是否为0,如果为0要给出警告
  3. 显示factor,如果factor的值为0,要将显示设为”0“,否则显示结果会为”0.0“
  4. 清零所有操作记录
public void equal(View v){
        factorSecond=Double.parseDouble(last);
        last="0";
        switch (flag){
            case 1:
                factor=factorFirst+factorSecond;
                break;
            case 2:
                factor=factorFirst-factorSecond;
                break;
            case 3:
                factor=factorFirst*factorSecond;
                break;
            case 4:
                if(factorSecond!=0)
                    factor=factorFirst/factorSecond;
                else {
                    Toast.makeText(this, "除数不能为0!", Toast.LENGTH_LONG).show();
                    break;
                }
                break;
        }
        if(factor==0)
            mResultText.setText("0");
        else
            mResultText.setText(factor.toString());
        clear();
    }

至此,一个完整、简单的计算器就实现了,但是还不能连续操作,有待改进。

发布了1 篇原创文章 · 获赞 0 · 访问量 344
展开阅读全文
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览