【Android应用开发之前端——简单计算器效果】

1.完成计算器布局

整个计算器界面主要分为两部分,一部分是上面的文本框,用于显示计算结果;另一部分是下面的几排按钮,用户输入数字与各种运算符。为了减少复杂度,我们可以精简一些功能,只保留数字与加、减、乘、除四则运算,另外补充一个开根号(求平方根)的运算。至于App的显示界面,基本与习惯的计算器界面保持一致,经过对操作按钮的适当排列,调整后的设计效果如下图所示:在这里插入图片描述
完成此界面用到了以下控件:
● 线性布局LinearLayout:计算器界面整体上是从上往下布局的,所以需要垂直方向的LinearLayout;下面部分每行都有4个按钮,又需要水平方向的LinearLayout。
● 滚动视图ScrollView:虽然计算器界面不宽也不高,但是以防万一,最好还是加个垂直方向的ScrollView。
● 文本视图TextView:很明显上方标题“简单计算器”就是TextView,下面的计算结果也需要使用TextView,而且是能够自动从下往上滚动的TextView,可参考前文聊天室效果的文本视图。
● 按钮Button:绝大多数数字与运算符按钮都采用Button控件。
● 图像按钮ImageButton:开根号的运算符“√”虽然能够打出来,但是右上角少了一横,所以该按钮要用一张标准的开根号图片显示,这就用到了ImageButton。
● 九宫格图片:注意计算器界面左下角的“0”,该按钮是其他按钮的两倍宽,如果使用普通图片当背景,势必会造成边缘线被拉宽、拉模糊的问题。故而要采用点九图片避免这种问题。

布局具体实现如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:orientation="vertical">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="30sp"
        android:text="简单计算器" />
    <TextView
        android:id="@+id/tv_result"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:scrollbars="vertical"
        android:textSize="25sp"
        android:background="@drawable/textview_border"/>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal">
        <Button
            android:text="CE"
            android:id="@+id/btn_cancel"
            style="@style/btn_cal" />
        <Button
            android:text="÷"
            android:id="@+id/btn_divide"
            style="@style/btn_cal" />
        <Button
            android:text="×"
            android:id="@+id/btn_multiply"
            style="@style/btn_cal" />
        <Button
            android:text="C"
            android:id="@+id/btn_clear"
            style="@style/btn_cal" />
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal">
        <Button
            android:text="7"
            android:id="@+id/btn_seven"
            style="@style/btn_cal" />
        <Button
            style="@style/btn_cal"
            android:id="@+id/btn_eight"
            android:text="8" />
        <Button
            android:text="9"
            android:id="@+id/btn_nine"
            style="@style/btn_cal" />
        <Button
            android:text="+"
            android:id="@+id/btn_plus"
            style="@style/btn_cal" />
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal">
        <Button
            android:text="4"
            android:id="@+id/btn_four"
            style="@style/btn_cal" />

        <Button
            style="@style/btn_cal"
            android:id="@+id/btn_five"
            android:text="5" />

        <Button
            android:text="6"
            android:id="@+id/btn_six"
            style="@style/btn_cal" />
        <Button
            android:text="-"
            android:id="@+id/btn_minus"
            style="@style/btn_cal" />
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal">
        <Button
            android:text="1"
            android:id="@+id/btn_one"
            style="@style/btn_cal" />
        <Button
            style="@style/btn_cal"
            android:id="@+id/btn_two"
            android:text="2" />
        <Button
            android:text="3"
            android:id="@+id/btn_three"
            style="@style/btn_cal" />
        <ImageButton
            android:id="@+id/btn_sqrt"
            android:src="@drawable/radical"
            android:scaleType="centerInside"
            style="@style/btn_cal" />
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal">
        <Button
            android:text="0"
            android:id="@+id/btn_zero"
            android:layout_weight="2"
            style="@style/btn_cal" />
        <Button
            android:text="."
            android:id="@+id/btn_dot"
            style="@style/btn_cal" />
        <Button
            android:text="="
            android:id="@+id/btn_equal"
            style="@style/btn_cal" />
    </LinearLayout>
</LinearLayout>

2.设置按钮风格、背景图片等

给按钮统一样式:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="btn_cal">
        <item name="android:layout_width">0dp</item>
        <item name="android:layout_height">match_parent</item>
        <item name="android:layout_weight">1</item>
        <item name="android:gravity">center</item>
        <item name="android:textColor">@color/black</item>
        <item name="android:textSize">30sp</item>
        <item name="android:background">@drawable/btn_bg</item>
        <item name="android:top">3dp</item>
        <item name="android:left">3dp</item>
        <item name="android:right">3dp</item>
        <item name="android:bottom">3dp</item>
    </style>
</resources>

为计算结果框设置边框

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:left="-1dp" android:right="-1dp"> <!--消除左边框和右边框-->
    <shape  android:shape="rectangle" >
        <solid android:color="#FFFFFF" />
        <stroke android:width="1dp" android:color="#000000"/>
    </shape>
    </item>
</layer-list>

3.完成计算器功能

package com.example.exercise;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import java.math.BigDecimal;

class Arith {
    //默认除法运算精度
    private static final int DEF_DIV_SCALE = 10;
    //构造器私有,让这个类不能实例化
    private Arith(){}
    //提供精确的加法运算
    public static double add(double v1,double v2){
        BigDecimal b1 = BigDecimal.valueOf(v1);
        BigDecimal b2 = BigDecimal.valueOf(v2);
        return b1.add(b2).doubleValue();
    }
    //提供精确的减法运算
    public static double sub(double v1,double v2){
        BigDecimal b1 = BigDecimal.valueOf(v1);
        BigDecimal b2 = BigDecimal.valueOf(v2);
        return b1.subtract(b2).doubleValue();
    }
    //提供精确的乘法运算
    public static double mul(double v1,double v2){
        BigDecimal b1 = BigDecimal.valueOf(v1);
        BigDecimal b2 = BigDecimal.valueOf(v2);
        return b1.multiply(b2).doubleValue();
    }
    //提供精确的除法运算
    public static double div(double v1,double v2){
        BigDecimal b1 = BigDecimal.valueOf(v1);
        BigDecimal b2 = BigDecimal.valueOf(v2);
        return b1.divide(b2).doubleValue();
    }
}

public class CalculatorActivity extends AppCompatActivity implements View.OnClickListener{
    private String operator = ""; //操作符
    private String firstNum = ""; //前一个操作数
    private String nextNum = ""; //后一个操作数
    private String result = ""; // 当前计算结果
    private String showText = ""; //显示的文本内容
    private TextView tv_result;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_calculator);
        tv_result = findViewById(R.id.tv_result);
        findViewById(R.id.btn_cancel).setOnClickListener(this);
        findViewById(R.id.btn_clear).setOnClickListener(this);
        findViewById(R.id.btn_equal).setOnClickListener(this);
        findViewById(R.id.btn_sqrt).setOnClickListener(this);
        findViewById(R.id.btn_divide).setOnClickListener(this);
        findViewById(R.id.btn_dot).setOnClickListener(this);
        findViewById(R.id.btn_eight).setOnClickListener(this);
        findViewById(R.id.btn_four).setOnClickListener(this);
        findViewById(R.id.btn_minus).setOnClickListener(this);
        findViewById(R.id.btn_multiply).setOnClickListener(this);
        findViewById(R.id.btn_nine).setOnClickListener(this);
        findViewById(R.id.btn_one).setOnClickListener(this);
        findViewById(R.id.btn_plus).setOnClickListener(this);
        findViewById(R.id.btn_seven).setOnClickListener(this);
        findViewById(R.id.btn_six).setOnClickListener(this);
        findViewById(R.id.btn_three).setOnClickListener(this);
        findViewById(R.id.btn_two).setOnClickListener(this);
        findViewById(R.id.btn_zero).setOnClickListener(this);
        findViewById(R.id.btn_five).setOnClickListener(this);
    }

    public void onClick(View v) {
        int resid = v.getId();
        String inputText;
        if (resid == R.id.btn_sqrt) {
            inputText = "√";
        } else {
            inputText = ((TextView) v).getText().toString();
        }
        Log.d("sqrt", "resid=" + resid + ",inputText=" + inputText);
        if (resid == R.id.btn_clear) {
            clear("0");
        } else if (resid == R.id.btn_cancel) {
            if (operator.equals("=") == true){
                Toast.makeText(this, "没有可取消的数字了", Toast.LENGTH_SHORT).show();
                return;
            }
            if (operator.equals("") == true) {
                if (firstNum.length() == 1) {
                    firstNum = "0";
                } else if (firstNum.length() > 0) {
                    firstNum = firstNum.substring(0, firstNum.length() - 1);
                } else if (showText == "0") {
                    firstNum = "0";
                } else {
                    Toast.makeText(this, "没有可取消的数字了", Toast.LENGTH_SHORT).show();
                }
                showText = firstNum;
                tv_result.setText(showText);
            } else {
                if (nextNum.length() == 1) {
                    nextNum = "";
                } else if (nextNum.length() > 0) {
                    nextNum = nextNum.substring(0, nextNum.length() - 1);
                } else {
                    Toast.makeText(this, "没有可取消的数字了", Toast.LENGTH_SHORT).show();
                    return;
                }
                showText = showText.substring(0, showText.length() - 1);
                tv_result.setText(showText);
            }
        } else if (resid == R.id.btn_equal) {
            if (operator.length() == 0 || operator.equals("=") == true) {
                Toast.makeText(this, "请输入运算符", Toast.LENGTH_SHORT).show();
                return;
            } else if (nextNum.length() <= 0) {
                Toast.makeText(this, "请输入数字", Toast.LENGTH_SHORT).show();
                return;
            }
            if(operator == "√"){
                if(convertToDouble(firstNum) < 0){
                    Toast.makeText(this, "开根号的数值不能小于0", Toast.LENGTH_SHORT).show();
                    return;
                }
                result = String.valueOf(Math.sqrt(convertToDouble(firstNum)));
                if((result.substring(result.length() - 2, result.length() - 1).equals(".") == true) && (result.substring(result.length() - 1).equals("0") == true)){
                    result = result.substring(0, result.length() - 2);
                }
                operator = inputText;
                showText = showText + "=" + result;
                tv_result.setText(showText);
            } else if (calculate() == true) {
                operator = inputText;
                showText = showText + "=" + result;
                tv_result.setText(showText);
            } else {
                return;
            }
        } else if(resid == R.id.btn_minus){
            if(operator.length() == 0 || operator.equals("=") == true || operator.equals("√") == true){
                operator = inputText;
                showText = showText + operator;
                tv_result.setText(showText);
            } else if(operator.length() == 1) {
                operator = inputText;
                showText = showText.substring(0, showText.length()-1) + operator;
                tv_result.setText(showText);
            }else{
                Toast.makeText(this, "请输入数字", Toast.LENGTH_SHORT).show();
                return;
            }
        } else if(resid == R.id.btn_plus || resid == R.id.btn_divide || resid == R.id.btn_multiply){
            if(firstNum.length() <= 0){
                Toast.makeText(this, "请输入数字", Toast.LENGTH_SHORT).show();
                return;
            }
            if(operator.length() == 0 || operator.equals("=") == true || operator.equals("√") == true){
                operator = inputText;
                showText = showText + operator;
                tv_result.setText(showText);
            } else if(operator.length() == 1) {
                operator = inputText;
                showText = showText.substring(0, showText.length()-1) + operator;
                tv_result.setText(showText);
            }else{
                Toast.makeText(this, "请输入数字", Toast.LENGTH_SHORT).show();
                return;
            }
        } else if(resid == R.id.btn_sqrt){
            if(showText == "0" || firstNum.equals("0") == true){
                firstNum = showText = "";
            }
            operator = inputText;
            showText = showText + operator;
            tv_result.setText(showText);
        } else{
            if(operator.equals("=") == true){
                operator = "";
                firstNum = "";
                showText = "";
            }
            if(operator.equals("√")){
                firstNum = firstNum + inputText;
                nextNum = "";
            }
            if(resid == R.id.btn_dot){
                inputText = ".";
            }
            if(operator.equals("") == true){
                if(showText == "0" || firstNum.equals("0") == true){
                    firstNum = showText = "";
                }
                firstNum = firstNum + inputText;
            } else {
                nextNum = nextNum + inputText;
            }
            showText = showText + inputText;
            tv_result.setText(showText);
        }
    }

    private double convertToDouble(String number){
        return Double.parseDouble(number);
    }

    private boolean calculate() {
        if (operator.equals("+") == true) {
            result = String.valueOf(Arith.add(convertToDouble(firstNum), convertToDouble(nextNum)));
        } else if (operator.equals("-") == true) {
            result = String.valueOf(Arith.sub(convertToDouble(firstNum), convertToDouble(nextNum)));
        } else if (operator.equals("×") == true) {
            result = String.valueOf(Arith.mul(convertToDouble(firstNum), convertToDouble(nextNum)));
        } else if (operator.equals("÷") == true) {
            if ("0".equals(nextNum)) {
                Toast.makeText(this, "被除数不能为零", Toast.LENGTH_SHORT).show();
                return false;
            } else {
                result = String.valueOf(Arith.div(convertToDouble(firstNum), convertToDouble(nextNum)));
            }
        }
        if((result.substring(result.length() - 2, result.length() - 1).equals(".") == true) && (result.substring(result.length() - 1).equals("0") == true)){
            result = result.substring(0, result.length() - 2);
        }
        firstNum = result;
        nextNum = "";
        return true;
    }

    private void clear(String text){
        showText = text;
        tv_result.setText(showText);
        operator = "";
        firstNum = "0";
        nextNum = "";
        result = "";
    }
}

整体效果如下:

在这里插入图片描述

  • 29
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wistain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值