Android:简易计算器

Android 计算器的简易实现

Github

私以为这个小项目中最难的是逻辑部分
目前资瓷加、减、乘、除、乘方,括号这些操作符
其中减号可以当做负号使用

AC长按清屏

特色:实时结果 数字分隔(100,000)
支持hentai算式 如3×-(-(-6+5)×2)

不足:还未加入自动调节字体大小功能
连续括号问题存在bug

图标

UI


预备知识

Android:控件中Button、Textview / EditText 的使用及布局方式
Java:集合,String及数组的熟练使用
算法:中缀转后缀及后缀表达式的计算 及复杂表达式的处理


UI

我的丑丑的UI是仿写手机中的一个计算器的界面,右边青色的的条条是可以划出来使用很多计算符的。但是还没学到,就先做个条条…

界面使用嵌套的线性布局实现

嵌套线性布局的使用技巧:先把布局块分好,再写控件,不然嵌套的多了,自己就容易写乱

上xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:weightSum="8">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="3"
        android:orientation="vertical"
        android:weightSum="5">

            <EditText
                android:id="@+id/text_screen"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="3"
                android:layout_gravity="right"
                android:gravity="right"
                android:focusable="false"
                android:cursorVisible="false"
                android:singleLine="true"
                android:background="@null"
                android:textColor="#666666"
                android:textSize="60sp" />

            <EditText
                android:id="@+id/text_result"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="2"
                android:layout_gravity="right"
                android:gravity="right"
                android:focusable="false"
                android:cursorVisible="false"
                android:singleLine="true"
                android:background="@null"
                android:textColor="#999999"
                android:textSize="40sp" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="5"
        android:weightSum="10"
        android:orientation="horizontal">
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="7"
            android:orientation="vertical"
            android:weightSum="5">
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:orientation="horizontal"
                android:weightSum="3">
                <Button
                    android:id="@+id/btn_leftBracket"
                    android:background="#333333"
                    android:textColor="#FFFFFF"
                    android:textSize="26sp"
                    android:text="("
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"/>
                <Button
                    android:id="@+id/btn_rightBracket"
                    android:background="#333333"
                    android:textColor="#FFFFFF"
                    android:textSize="26sp"
                    android:text=")"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"/>
                <Button
                    android:id="@+id/btn_power"
                    android:background="#333333"
                    android:textColor="#FFFFFF"
                    android:textSize="26sp"
                    android:text="^"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"/>
            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:weightSum="3">
                <Button
                    android:id="@+id/btn_1"
                    android:background="#333333"
                    android:textColor="#FFFFFF"
                    android:textSize="26sp"
                    android:text="1"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"/>
                <Button
                    android:id="@+id/btn_2"
                    android:background="#333333"
                    android:textColor="#FFFFFF"
                    android:textSize="26sp"
                    android:text="2"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"/>
                <Button
                    android:id="@+id/btn_3"
                    android:background="#333333"
                    android:textColor="#FFFFFF"
                    android:textSize="26sp"
                    android:text="3"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"/>
            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:weightSum="3">
                <Button
                    android:id="@+id/btn_4"
                    android:background="#333333"
                    android:textColor="#FFFFFF"
                    android:textSize="26sp"
                    android:text="4"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"/>
                <Button
                    android:id="@+id/btn_5"
                    android:background="#333333"
                    android:textColor="#FFFFFF"
                    android:textSize="26sp"
                    android:text="5"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"/>
                <Button
                    android:id="@+id/btn_6"
                    android:background="#333333"
                    android:textColor="#FFFFFF"
                    android:textSize="26sp"
                    android:text="6"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"/>
            </LinearLayout>
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:weightSum="3">
                <Button
                    android:id="@+id/btn_7"
                    android:background="#333333"
                    android:textColor="#FFFFFF"
                    android:textSize="26sp"
                    android:text="7"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"/>
                <Button
                    android:id="@+id/btn_8"
                    android:background="#333333"
                    android:textColor="#FFFFFF"
                    android:textSize="26sp"
                    android:text="8"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"/>
                <Button
                    android:id="@+id/btn_9"
                    android:background="#333333"
                    android:textColor="#FFFFFF"
                    android:textSize="26sp"
                    android:text="9"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"/>
            </LinearLayout>
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:weightSum="3">
                <Button
                    android:id="@+id/btn_del"
                    android:background="#333333"
                    android:textColor="#FFFFFF"
                    android:textSize="26sp"
                    android:text="."
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"/>
                <Button
                    android:id="@+id/btn_0"
                    android:background="#333333"
                    android:textColor="#FFFFFF"
                    android:textSize="26sp"
                    android:text="0"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"/>
                <Button
                    android:id="@+id/btn_calculate"
                    android:background="#333333"
                    android:textColor="#FFFFFF"
                    android:textSize="26sp"
                    android:text="="
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"/>
            </LinearLayout>
        </LinearLayout>
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="3"
            android:weightSum="4">
            <LinearLayout
                android:orientation="vertical"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="3"
                android:weightSum="5">
                <Button
                    android:id="@+id/btn_clear"
                    android:background="#666666"
                    android:textColor="#FFFFFF"
                    android:textSize="26sp"
                    android:text="AC"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"/>
                <Button
                    android:id="@+id/btn_devide"
                    android:background="#666666"
                    android:textColor="#FFFFFF"
                    android:textSize="26sp"
                    android:text="÷"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"/>
                <Button
                    android:id="@+id/btn_multiply"
                    android:background="#666666"
                    android:textColor="#FFFFFF"
                    android:textSize="26sp"
                    android:text="×"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"/>
                <Button
                    android:id="@+id/btn_minus"
                    android:background="#666666"
                    android:textColor="#FFFFFF"
                    android:textSize="26sp"
                    android:text="-"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"/>
                <Button
                    android:id="@+id/btn_plus"
                    android:background="#666666"
                    android:textColor="#FFFFFF"
                    android:textSize="26sp"
                    android:text="+"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"/>
            </LinearLayout>

            <LinearLayout
                android:background="#00FFFC"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1">

            </LinearLayout>

        </LinearLayout>
    </LinearLayout>


</LinearLayout>

逻辑

写了两个工具类
StringExam类辅助字符串处理,Calculate类进行计算

计算思想,从文本框中取得字符串,检查处理,重点处理– ( )×–÷–,转为后缀表达式再计算

代码太长Github自取


UI与逻辑的交互代码

看到好多学长制造Button注册监听器就写了几十行….
注册监听器可以跟findViewById写到一起
其实看一下R.java中的代码,连着写的控件,id是连着的。而且这部分代码是可修改的。所以用int类型的数就可以批量注册

后面的 switch case也是同理,数字部分明明可以合并,略去好多重复代码

package com.example.hp.calculator;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import java.text.Format;

import static com.example.hp.calculator.Calculate.arrange;
import static com.example.hp.calculator.StringExam.*;

public class InteractActivity extends AppCompatActivity implements View.OnClickListener{

    private StringBuffer text = new StringBuffer();
    private TextView edit_screen;
    private TextView result_screen;
    private String s = new String();
    private boolean flag = false;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.module_activity_main);
        //0x7f070022 ~0032
        int id = 0x7f070022;
        for(id=0x7f070022;id<=0x7f070034;id++){
            findViewById(id).setOnClickListener(this);
        }
        findViewById(R.id.btn_clear).setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                text = new StringBuffer();
                s = "";
                edit_screen.setText("0");
                result_screen.setText("");
                return false;
            }
        });
        edit_screen = findViewById(R.id.text_screen);
        result_screen = findViewById(R.id.text_result);
        findViewById(R.id.btn_leftBracket).setOnClickListener(this);
        findViewById(R.id.btn_rightBracket).setOnClickListener(this);
//        edit_screen.setMovementMethod(ScrollingMovementMethod.getInstance());
    }


    @Override
    public void onClick(View view) {
        int textLen = text.length();
        switch (view.getId()){
            case R.id.btn_0:
                if(flag){
                    text = new StringBuffer();
                    textLen = 0;
                }
                if(textLen==0||text.charAt(textLen-1)!=')')
                    text.append('0');
                break;
            case R.id.btn_1://0x7f070022
            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:
                if(flag){
                    text = new StringBuffer();
                    textLen = 0;
                }
                if(textLen==0||text.charAt(textLen-1)!=')')
                    text.append((char) ('1'+view.getId()-0x7f070023));
                break;
                //根据id判断所加字符
            case R.id.btn_del:
                if(textLen==0)
                    text.append("0.");
                else if(isNum(text.charAt(textLen-1))&&judgeDel(text.toString())==false)
                    text.append('.');
                break;
            case R.id.btn_leftBracket:
                if(textLen==0||(textLen>0&&text.charAt(textLen-1)!='.'&&isNum(text.charAt(textLen-1))==false))
                    text.append('(');
                    break;
            case R.id.btn_rightBracket:
                if(cntBrackets(text.toString())>0&&textLen>0&&!isOperation(text.charAt(textLen-1))&&text.charAt(textLen-1)!='.'&&text.charAt(textLen-1)!='(')
                    text.append(')');
                break;
            case R.id.btn_plus:
                //if(textLen>0&&!isOperation(text.charAt(textLen-1))&&text.charAt(textLen-1)!='.')
                if(textLen>0&&(isNum(text.charAt(textLen-1))||text.charAt(textLen-1)==')'))
                    text.append('+');
                else if(textLen>0&&cntCharacter(text.toString())==1)
                    text.setCharAt(textLen-1,'+');
                break;
            case R.id.btn_minus:
//             if(textLen==0||(text.charAt(textLen-1)!='+'&&text.charAt(textLen-1)!='-'&&text.charAt(textLen-1)!='.'))
                if(textLen==0)
                    text.append('-');
                else if(textLen==1){
                    if(text.charAt(textLen-1)!='-')
                    text.append('-');
                }
                else if(textLen == 2&&text.charAt(0)=='('){
                    if(text.charAt(1)!='-')
                        text.append('-');
                }
                else if(text.charAt(textLen-1)!='.'&&cntCharacter(text.toString())<2||(cntCharacter(text.toString())==2&&(text.charAt(textLen-1)!='-'&&text.charAt(textLen-2)!='-'))||text.charAt(textLen-1)=='(')
                    text.append('-');
//                if(textLen>0){
//                    Toast.makeText(this,String.valueOf(text.charAt(textLen-1)!='.'&&cntCharacter(text.toString())<=2||(textLen==1&&text.charAt(textLen-1)!='-')),Toast.LENGTH_SHORT).show();
//                }
                break;
            case R.id.btn_multiply:
                if(textLen>0&&(isNum(text.charAt(textLen-1))||text.charAt(textLen-1)==')'))
                    text.append('×');
                else if(textLen>0&&cntCharacter(text.toString())==1)
                    text.setCharAt(textLen-1,'×');
                break;
            case R.id.btn_devide:
                if(textLen>0&&(isNum(text.charAt(textLen-1))||text.charAt(textLen-1)==')'))
                    text.append('÷');
                else if(textLen>0&&cntCharacter(text.toString())==1)
                    text.setCharAt(textLen-1,'÷');
                break;
            case R.id.btn_power:
                if(textLen>0&&(isNum(text.charAt(textLen-1))||text.charAt(textLen-1)==')'))
                    text.append('^');
                else if(cntCharacter(text.toString())==1){
                    text.setCharAt(textLen-1,'^');
                }
                break;
            case R.id.btn_clear:
                if(textLen>0)
                    text.deleteCharAt(textLen-1);
                if(text.length()==0)
                    s="";
                break;
            case R.id.btn_calculate:
                if(!edit_screen.getText().equals(result_screen.getText())){
                    flag = true;}
                try{
                    text = new StringBuffer(s);
                 //嘻嘻嘻
                    edit_screen.setText(devideByDel(s));
                    result_screen.setText("");
                } catch (Exception e){
                    edit_screen.setText("bug發現,請聯繫開發者kafm。QQ1002605741");
                    text = new StringBuffer();
                    s = "";
                }
                break;
        }
        if(view.getId()!=R.id.btn_calculate){
            flag = false;
//            String tem = devideByDel();
            edit_screen.setText(parseStringAndDevideByDel(text.toString()));//可用正则表达式优化
            if(text.length()>0)
                s = completeString(text.toString());
            if(s.length()>0) {
                try {
                    s=arrange(s);
                } catch (infinityException e) {
                    s = "∞";
                } catch (Exception e) {
//坑
                }
            }
            result_screen.setText(devideByDel(s));
        }
    }
}

2018/8/4

原文地址:https://www.cnblogs.com/kafm/p/12721850.html