java编写安卓计算器_[记录]Android简单计算器实现1(java)

这篇博客记录了使用Java开发Android简单计算器的过程。参照一加计算器设计,实现了四则运算及小数点功能。计算器布局使用XML,按钮事件在MainActivity.java中处理,运用栈实现表达式计算。目前尚不支持括号和百分比运算。
摘要由CSDN通过智能技术生成

介绍

初学Android开发,在官方开发者网站https://developer.android.com/guide学完构建简单的应用后就开始尝试实现简单的计算器app。计算器的实现是参照一加手机的计算器设计,这里实现了计算器的表达式输入并输出运算结果,支持小数的四则运算。

工具:IntelliJ IDEA

语言:Java

app效果

界面上面有两个TextView分别显示输入的运算表达式和计算结果;下方20个Button按钮实现按键功能。app中 % 和 ( ) 还未实现。

可以输入数字和+-*/运算符,当为输入数字时不能输入运算符;小数点'.'也算运算符;不允许连续输入运算符(123+*不允许);超过double范围的数自动转为科学计数法显示。

输入要计算的表达式后按'='按钮会显示运算结果。

3d1f2bded163205ca3ef99396fd912d6.png

实现

通过android Activity绘制计算器的界面并设计组件布局

bf195d3b8325f22d233cf52219b9fb25.png

布局的activity_main.xml内容如下

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

xmlns:app="http://schemas.android.com/apk/res-auto"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context=".MainActivity">

android:text="( )"

android:layout_width="80dp"

android:layout_height="60dp" android:id="@+id/sign_bracket"

app:layout_constraintBottom_toBottomOf="parent"

android:layout_marginBottom="16dp" app:layout_constraintStart_toEndOf="@+id/number0"

app:layout_constraintHorizontal_bias="0.5" app:layout_constraintEnd_toStartOf="@+id/sign_equal"

app:layout_constraintTop_toBottomOf="@+id/number3" android:textSize="30sp"

android:fontFamily="sans-serif" android:background="#FFFFFF"/>

android:text="/"

android:layout_width="80dp"

android:layout_height="60dp" android:id="@+id/sign_divide"

app:layout_constraintStart_toEndOf="@+id/sign_rest"

app:layout_constraintHorizontal_bias="0.5" app:layout_constraintEnd_toEndOf="parent"

app:layout_constraintTop_toBottomOf="@+id/num_result"

app:layout_constraintBottom_toTopOf="@+id/sign_multiply" android:textSize="30sp"

android:fontFamily="sans-serif" android:background="#FFFFFF" android:textColor="#FF9800"

/>

android:text="%"

android:layout_width="80dp"

android:layout_height="60dp" android:id="@+id/sign_rest"

app:layout_constraintStart_toEndOf="@+id/sign_del"

app:layout_constraintHorizontal_bias="0.5" app:layout_constraintEnd_toStartOf="@+id/sign_divide"

app:layout_constraintTop_toBottomOf="@+id/num_result"

app:layout_constraintBottom_toTopOf="@+id/number9" android:textSize="30sp"

android:fontFamily="sans-serif" android:background="#FFFFFF"/>

android:text="DEL"

android:layout_width="80dp"

android:layout_height="60dp" android:id="@+id/sign_del"

app:layout_constraintStart_toEndOf="@+id/sign_ac"

app:layout_constraintHorizontal_bias="0.5" app:layout_constraintEnd_toStartOf="@+id/sign_rest"

app:layout_constraintTop_toBottomOf="@+id/num_result"

app:layout_constraintBottom_toTopOf="@+id/number8" android:textSize="30sp"

android:fontFamily="sans-serif" android:background="#FFFFFF"/>

android:text="AC"

android:layout_width="80dp"

android:layout_height="60dp" android:id="@+id/sign_ac"

app:layout_constraintStart_toStartOf="parent" app:layout_constraintHorizontal_bias="0.5"

app:layout_constraintEnd_toStartOf="@+id/sign_del" app:layout_constraintTop_toBottomOf="@+id/num_result"

app:layout_constraintBottom_toTopOf="@+id/number7"

android:textSize="30sp" android:fontFamily="sans-serif" android:background="#FFFFFF"/>

android:text="."

android:layout_width="80dp"

android:layout_height="60dp" android:id="@+id/sign_point"

app:layout_constraintBottom_toBottomOf="parent"

android:layout_marginBottom="16dp" app:layout_constraintStart_toStartOf="parent"

app:layout_constraintHorizontal_bias="0.5" app:layout_constraintEnd_toStartOf="@+id/number0"

app:layout_constraintTop_toBottomOf="@+id/number1" android:textSize="30sp"

android:fontFamily="sans-serif" android:background="#FFFFFF"/>

android:text="8"

android:layout_width="80dp"

android:layout_height="60dp" android:id="@+id/number8"

app:layout_constraintStart_toEndOf="@+id/number7"

app:layout_constraintHorizontal_bias="0.5" app:layout_constraintEnd_toStartOf="@+id/number9"

app:layout_constraintTop_toBottomOf="@+id/sign_del" app:layout_constraintBottom_toTopOf="@+id/number5"

android:textSize="30sp" android:fontFamily="sans-serif" android:background="#FFFFFF"/>

android:text="9"

android:layout_width="80dp"

android:layout_height="60dp" android:id="@+id/number9"

app:layout_constraintStart_toEndOf="@+id/number8"

app:layout_constraintHorizontal_bias="0.5" app:layout_constraintEnd_toStartOf="@+id/sign_multiply"

app:layout_constraintTop_toBottomOf="@+id/sign_rest" app:layout_constraintBottom_toTopOf="@+id/number6"

android:textSize="30sp" android:fontFamily="sans-serif" android:background="#FFFFFF"/>

android:text="*"

android:layout_width="80dp"

android:layout_height="60dp" android:id="@+id/sign_multiply"

app:layout_constraintStart_toEndOf="@+id/number9"

app:layout_constraintHorizontal_bias="0.5" app:layout_constraintEnd_toEndOf="parent"

app:layout_constraintTop_toBottomOf="@+id/sign_divide" app:layout_constraintBottom_toTopOf="@+id/sign_sub"

android:textSize="30sp" android:fontFamily="sans-serif" android:background="#FFFFFF"

android:textColor="#FF9800"/>

android:text="4"

android:layout_width="80dp"

android:layout_height="60dp" android:id="@+id/number4"

app:layout_constraintStart_toStartOf="parent"

app:layout_constraintHorizontal_bias="0.5" app:layout_constraintEnd_toStartOf="@+id/number5"

app:layout_constraintTop_toBottomOf="@+id/number7" app:layout_constraintBottom_toTopOf="@+id/number1"

android:textSize="30sp" android:fontFamily="sans-serif" android:background="#FFFFFF"/>

android:text="5"

android:layout_width="80dp"

android:layout_height="60dp" android:id="@+id/number5"

app:layout_constraintStart_toEndOf="@+id/number4"

app:layout_constraintHorizontal_bias="0.5" app:layout_constraintEnd_toStartOf="@+id/number6"

app:layout_constraintTop_toBottomOf="@+id/number8" app:layout_constraintBottom_toTopOf="@+id/number2"

android:textSize="30sp" android:fontFamily="sans-serif" android:background="#FFFFFF"/>

android:text="6"

android:layout_width="80dp"

android:layout_height="60dp" android:id="@+id/number6"

app:layout_constraintStart_toEndOf="@+id/number5"

app:layout_constraintHorizontal_bias="0.5" app:layout_constraintEnd_toStartOf="@+id/sign_sub"

app:layout_constraintTop_toBottomOf="@+id/number9" app:layout_constraintBottom_toTopOf="@+id/number3"

android:textSize="30sp" android:fontFamily="sans-serif" android:background="#FFFFFF"/>

android:text="-"

android:layout_width="80dp"

android:layout_height="60dp" android:id="@+id/sign_sub"

app:layout_constraintStart_toEndOf="@+id/number6"

app:layout_constraintHorizontal_bias="0.5" app:layout_constraintEnd_toEndOf="parent"

app:layout_constraintTop_toBottomOf="@+id/sign_multiply" app:layout_constraintBottom_toTopOf="@+id/sign_add"

android:textSize="30sp" android:fontFamily="sans-serif" android:background="#FFFFFF"

android:textColor="#FF9800"/>

android:text="1"

android:layout_width="80dp"

android:layout_height="60dp" android:id="@+id/number1"

app:layout_constraintStart_toStartOf="parent"

app:layout_constraintHorizontal_bias="0.5" app:layout_constraintEnd_toStartOf="@+id/number2"

app:layout_constraintTop_toBottomOf="@+id/number4" app:layout_constraintBottom_toTopOf="@+id/sign_point"

android:textSize="30sp" android:fontFamily="sans-serif" android:background="#FFFFFF"/>

android:text="2"

android:layout_width="80dp"

android:layout_height="60dp" android:id="@+id/number2"

app:layout_constraintStart_toEndOf="@+id/number1"

app:layout_constraintHorizontal_bias="0.5" app:layout_constraintEnd_toStartOf="@+id/number3"

app:layout_constraintTop_toBottomOf="@+id/number5" app:layout_constraintBottom_toTopOf="@+id/number0"

android:textSize="30sp" android:fontFamily="sans-serif" android:background="#FFFFFF"/>

android:text="3"

android:layout_width="80dp"

android:layout_height="60dp" android:id="@+id/number3"

app:layout_constraintStart_toEndOf="@+id/number2"

app:layout_constraintHorizontal_bias="0.5" app:layout_constraintEnd_toStartOf="@+id/sign_add"

app:layout_constraintTop_toBottomOf="@+id/number6" app:layout_constraintBottom_toTopOf="@+id/sign_bracket"

android:textSize="30sp" android:fontFamily="sans-serif" android:background="#FFFFFF"/>

android:text="0"

android:layout_width="80dp"

android:layout_height="60dp" android:id="@+id/number0"

app:layout_constraintBottom_toBottomOf="parent"

android:layout_marginBottom="16dp" app:layout_constraintStart_toEndOf="@+id/sign_point"

app:layout_constraintHorizontal_bias="0.5" app:layout_constraintEnd_toStartOf="@+id/sign_bracket"

app:layout_constraintTop_toBottomOf="@+id/number2" android:textSize="30sp"

android:fontFamily="sans-serif" android:background="#FFFFFF"/>

android:text="+"

android:layout_width="80dp"

android:layout_height="60dp" android:id="@+id/sign_add"

app:layout_constraintStart_toEndOf="@+id/number3"

app:layout_constraintHorizontal_bias="0.5" app:layout_constraintEnd_toEndOf="parent"

app:layout_constraintTop_toBottomOf="@+id/sign_sub" app:layout_constraintBottom_toTopOf="@+id/sign_equal"

android:textSize="30sp" android:fontFamily="sans-serif" android:background="#FFFFFF"

android:textColor="#FF9800"/>

android:text="7"

android:layout_width="80dp"

android:layout_height="60dp" android:id="@+id/number7"

app:layout_constraintStart_toStartOf="parent"

app:layout_constraintHorizontal_bias="0.5" app:layout_constraintEnd_toStartOf="@+id/number8"

app:layout_constraintTop_toBottomOf="@+id/sign_ac" app:layout_constraintBottom_toTopOf="@+id/number4"

android:textSize="30sp" android:fontFamily="sans-serif" android:background="#FFFFFF"/>

android:text="="

android:layout_width="80dp"

android:layout_height="60dp" android:id="@+id/sign_equal"

app:layout_constraintBottom_toBottomOf="parent"

app:layout_constraintEnd_toEndOf="parent"

app:layout_constraintStart_toEndOf="@+id/sign_bracket" app:layout_constraintHorizontal_bias="0.5"

android:layout_marginBottom="16dp" app:layout_constraintTop_toBottomOf="@+id/sign_add"

android:textSize="36sp" android:fontFamily="sans-serif" android:background="#ABFF9800"

android:textStyle="bold"/>

android:layout_width="363dp"

android:layout_height="40dp" app:layout_constraintStart_toStartOf="parent"

app:layout_constraintEnd_toEndOf="parent" android:id="@+id/num_result"

android:layout_marginStart="20dp" android:layout_marginEnd="20dp"

app:layout_constraintTop_toBottomOf="@+id/num_calculate" android:textSize="30sp"

android:textAlignment="viewEnd" android:textColor="#9F9F9F"/>

android:layout_width="363dp"

android:layout_height="117dp" app:layout_constraintStart_toStartOf="parent"

app:layout_constraintEnd_toEndOf="parent" android:id="@+id/num_calculate"

app:layout_constraintHorizontal_bias="0.5" android:layout_marginStart="20dp"

android:layout_marginEnd="20dp" app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="20dp"

android:textStyle="bold" android:textAlignment="viewEnd" android:textSize="36sp"

android:gravity="center"/>

接下来是MainActivity.java文件实现计算器的功能。计算器实现参照了网上的实现方法实现按钮事件(见参考的csnd博客);并且我融合了leetcode中通过栈实现四则运算的算法,在算法的基础上进行小的修改使其能支持小数(double)。

package com.example.MyApp;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.View;

import android.widget.Button;

import android.view.View.OnClickListener;

import android.widget.TextView;

import java.util.LinkedList;

import java.util.Stack;

public class MainActivity extends AppCompatActivity{

private Button btn_0;

private Button btn_1;

private Button btn_2;

private Button btn_3;

private Button btn_4;

private Button btn_5;

private Button btn_6;

private Button btn_7;

private Button btn_8;

private Button btn_9;

private Button btn_point;// .小数点

private Button btn_ac;// ac

private Button btn_del;// del

private Button btn_add;// +

private Button btn_sub;// -

private Button btn_multply;// *

private Button btn_divide;// /

private Button btn_equal;// =

private TextView _calculate;//算数表达式

private TextView _result;//结果

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

btn_0 = (Button)findViewById(R.id.number0);

btn_1 = (Button)findViewById(R.id.number1);

btn_2 = (Button)findViewById(R.id.number2);

btn_3 = (Button)findViewById(R.id.number3);

btn_4 = (Button)findViewById(R.id.number4);

btn_5 = (Button)findViewById(R.id.number5);

btn_6 = (Button)findViewById(R.id.number6);

btn_7 = (Button)findViewById(R.id.number7);

btn_8 = (Button)findViewById(R.id.number8);

btn_9 = (Button)findViewById(R.id.number9);

btn_point = (Button)findViewById(R.id.sign_point);

btn_ac = (Button)findViewById(R.id.sign_ac);

btn_del = (Button)findViewById(R.id.sign_del);

btn_add = (Button)findViewById(R.id.sign_add);

btn_sub = (Button)findViewById(R.id.sign_sub);

btn_multply = (Button)findViewById(R.id.sign_multiply);

btn_divide = (Button)findViewById(R.id.sign_divide);

btn_equal = (Button)findViewById(R.id.sign_equal);

_calculate = (TextView) findViewById(R.id.num_calculate);

_result = (TextView) findViewById(R.id.num_result);

btn_0.setOnClickListener(ClickInHere);

btn_1.setOnClickListener(ClickInHere);

btn_2.setOnClickListener(ClickInHere);

btn_3.setOnClickListener(ClickInHere);

btn_4.setOnClickListener(ClickInHere);

btn_5.setOnClickListener(ClickInHere);

btn_6.setOnClickListener(ClickInHere);

btn_7.setOnClickListener(ClickInHere);

btn_8.setOnClickListener(ClickInHere);

btn_9.setOnClickListener(ClickInHere);

btn_point.setOnClickListener(ClickInHere);

btn_ac.setOnClickListener(ClickInHere);

btn_del.setOnClickListener(ClickInHere);

btn_add.setOnClickListener(ClickInHere);

btn_sub.setOnClickListener(ClickInHere);

btn_multply.setOnClickListener(ClickInHere);

btn_divide.setOnClickListener(ClickInHere);

btn_equal.setOnClickListener(ClickInHere);

}

private OnClickListener ClickInHere = new OnClickListener() {

@Override

public void onClick(View v) {

String input = _calculate.getText().toString();

switch (v.getId()){

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:

_calculate.setText(input+((Button)v).getText());

break;

case R.id.sign_point:

case R.id.sign_add:

case R.id.sign_sub:

case R.id.sign_multiply:

case R.id.sign_divide:

if(input!=null&&!input.equals("")) {

//不允许连续输入多个运算符

char c=input.charAt(input.length()-1);

if((byte)c>41&&(byte)c<48){

//acsii的42-47为* + , - . /

_calculate.setText(input.substring(0, input.length()-1)+((Button) v).getText());

}else{

_calculate.setText(input + ((Button) v).getText());

}

}

break;

case R.id.sign_ac:

//第一次ac清空_calculate,第二次清空_result

if(input.equals("")){

//_calculate为空则清空计算结果

_result.setText("");

}

input = "";

_calculate.setText(input);

break;

case R.id.sign_equal:

//_result显示运算结果

_result.setText(getResult());

break;

case R.id.sign_del:

if(input!=null&&!input.equals("")){

_calculate.setText(input.substring(0, input.length() - 1));

}

break;

default:

// %和( )未实现

break;

}

}

};

private String getResult(){

String cal = _calculate.getText().toString();

if(cal==null||cal.equals(""))

return "";

double resnum = 0;

resnum=calRst(backTempcal(cal));

//resnum小数位为0输出整形int

String resstr;

if(resnum%1==0){

resstr=String.valueOf((int)resnum);

}else{

resstr=String.valueOf(resnum);

}

return resstr;

}

//leetcode的四则运算算法,将数字类型改为double并在其中加入小数的运算

/*作者:nopdes1resun

*链接:https://leetcode-cn.com/problems/basic-calculator-ii/solution/zhan-de-jing-dian-ying-yong-ji-suan-qi-by-nopdes1r/

*来源:力扣(LeetCode)

*/

public static double calRst(LinkedList tempBackcal) {

Stack calStk = new Stack();

for (String c : tempBackcal) {

// 1.数字,入栈

if (isNumeric(c)) {

calStk.push(Double.valueOf(c)); // string to int

continue;

}

// 2.非数字,则为符号,出栈两个元素计算出结果然后再入栈该计算值

else {

Double a = calStk.pop();

Double b = calStk.pop();

switch (c.toCharArray()[0]) {

// 注意减法和除法时,注意出栈的顺序与原表达式是相反的

case '+':

calStk.push(b + a);

continue;

case '-':

calStk.push(b - a);

continue;

case '*':

calStk.push(b * a);

continue;

case '/':

calStk.push(b / a);

continue;

}

}

}

return calStk.pop();

}

// 计算后缀表达式

public static LinkedList backTempcal(String cal) {

Stack stkEles = new Stack();

LinkedList tempBackcal = new LinkedList();

for (int i = 0; i < cal.length(); i++) {

// 1.遇到了数字

if (Character.isDigit(cal.charAt(i))) {

// 注意多位数的获取

int k = i + 1;

//小数点也加入数字中

for (; k < cal.length() && (Character.isDigit(cal.charAt(k))||cal.charAt(k)=='.'); k++) {

}

tempBackcal.add(cal.substring(i, k));

i = k - 1;// 更新 i

continue;

}

// 2.遇到了乘除运算符

if (cal.charAt(i) == '/' || cal.charAt(i) == '*') {

while (!stkEles.isEmpty() && (stkEles.lastElement().equals("/") || stkEles.lastElement().equals("*"))) {

tempBackcal.add(stkEles.pop()); // 弹出优先级相同或以上的栈内运算符

}

stkEles.add(String.valueOf(cal.charAt(i))); // 运算符入栈

continue;

}

// 3.遇到了加减运算符

if (cal.charAt(i) == '+' || cal.charAt(i) == '-') {

while (!stkEles.isEmpty() && !isNumeric(stkEles.lastElement())) {

tempBackcal.add(stkEles.pop()); // 弹出优先级相同或以上的栈内运算符

}

stkEles.add(String.valueOf(cal.charAt(i))); // 运算符入栈

continue;

}

}

// 4.最后弹出栈内所有元素到表达式

while (stkEles.size() > 0) {

tempBackcal.add(stkEles.pop());

}

return tempBackcal;

}

//判断是否为数字

public static boolean isNumeric(String str) {

for (int i = 0; i < str.length(); i++) {

//是否为数字或者小数点

if (!Character.isDigit(str.charAt(i))&&str.charAt(i)!='.') {

return false;

}

}

return true;

}

}

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值