一、UI布局及代码
页面效果 布局代码
<?xml version="1.0" encoding="utf-8"?>
< LinearLayout xmlns: android= " http://schemas.android.com/apk/res/android" android: layout_width= " match_parent" android: layout_height= " match_parent" android: orientation= " vertical" android: weightSum= " 8" > < TextViewandroid: layout_width= " match_parent" android: layout_height= " 0dp" android: id= " @+id/text_view" android: layout_weight= " 2" android: textSize= " 70dp" android: gravity= " right|bottom" android: maxLines= " 2" /> < TextViewandroid: id= " @+id/result_view" android: layout_width= " match_parent" android: layout_height= " 0dp" android: layout_weight= " 1" android: gravity= " right|bottom" android: maxLines= " 1" android: textSize= " 65dp" /> < LinearLayoutandroid: layout_width= " match_parent" android: layout_height= " 0dp" android: layout_weight= " 1" android: orientation= " horizontal" android: weightSum= " 5" > < Buttonandroid: layout_width= " 0dp" android: layout_height= " match_parent" android: id= " @+id/button_ac" android: layout_weight= " 1" android: text= " AC" android: background= " #ff0000" android: textColor= " #000" android: textSize= " 20dp" android: layout_margin= " 5dp" /> < Buttonandroid: layout_width= " 0dp" android: layout_height= " match_parent" android: id= " @+id/button_left" android: layout_weight= " 1" android: text= " (" android: background= " #fff" android: textColor= " #000" android: textSize= " 30dp" android: layout_margin= " 5dp" /> < Buttonandroid: layout_width= " 0dp" android: layout_height= " match_parent" android: id= " @+id/button_right" android: layout_weight= " 1" android: text= " )" android: background= " #fff" android: textColor= " #000" android: textSize= " 30dp" android: layout_margin= " 5dp" /> < Buttonandroid: layout_width= " 0dp" android: layout_height= " match_parent" android: id= " @+id/button_divide" android: layout_weight= " 1" android: text= " /" android: background= " #fffaf0" android: textColor= " #000" android: textSize= " 30dp" android: layout_margin= " 5dp" /> < Buttonandroid: layout_width= " 0dp" android: layout_height= " match_parent" android: id= " @+id/button_del" android: layout_weight= " 1" android: text= " DEL" android: background= " #808a87" android: textColor= " #000" android: textSize= " 15dp" android: layout_margin= " 5dp" /> </ LinearLayout> < LinearLayoutandroid: layout_width= " match_parent" android: layout_height= " 0dp" android: layout_weight= " 1" android: orientation= " horizontal" android: weightSum= " 4" > < Buttonandroid: layout_width= " 0dp" android: layout_height= " match_parent" android: id= " @+id/button_7" android: layout_weight= " 1" android: text= " 7" android: textColor= " #000" android: textSize= " 30dp" android: layout_margin= " 5dp" /> < Buttonandroid: layout_width= " 0dp" android: layout_height= " match_parent" android: id= " @+id/button_8" android: layout_weight= " 1" android: text= " 8" android: textColor= " #000" android: textSize= " 30dp" android: layout_margin= " 5dp" /> < Buttonandroid: layout_width= " 0dp" android: layout_height= " match_parent" android: id= " @+id/button_9" android: layout_weight= " 1" android: text= " 9" android: textColor= " #000" android: textSize= " 30dp" android: layout_margin= " 5dp" /> < Buttonandroid: layout_width= " 0dp" android: layout_height= " match_parent" android: id= " @+id/button_mult" android: layout_weight= " 1" android: text= " *" android: background= " #fffaf0" android: textColor= " #000" android: textSize= " 30dp" android: layout_margin= " 5dp" /> </ LinearLayout> < LinearLayoutandroid: layout_width= " match_parent" android: layout_height= " 0dp" android: layout_weight= " 1" android: orientation= " horizontal" android: weightSum= " 4" > < Buttonandroid: layout_width= " 0dp" android: layout_height= " match_parent" android: id= " @+id/button_4" android: layout_weight= " 1" android: text= " 4" android: textColor= " #000" android: textSize= " 30dp" android: layout_margin= " 5dp" /> < Buttonandroid: layout_width= " 0dp" android: layout_height= " match_parent" android: id= " @+id/button_5" android: layout_weight= " 1" android: text= " 5" android: textColor= " #000" android: textSize= " 30dp" android: layout_margin= " 5dp" /> < Buttonandroid: layout_width= " 0dp" android: layout_height= " match_parent" android: id= " @+id/button_6" android: layout_weight= " 1" android: text= " 6" android: textColor= " #000" android: textSize= " 30dp" android: layout_margin= " 5dp" /> < Buttonandroid: layout_width= " 0dp" android: layout_height= " match_parent" android: id= " @+id/button_add" android: layout_weight= " 1" android: text= " +" android: background= " #fffaf0" android: textColor= " #000" android: textSize= " 30dp" android: layout_margin= " 5dp" /> </ LinearLayout> < LinearLayoutandroid: layout_width= " match_parent" android: layout_height= " 0dp" android: layout_weight= " 1" android: orientation= " horizontal" android: weightSum= " 4" > < Buttonandroid: layout_width= " 0dp" android: layout_height= " match_parent" android: id= " @+id/button_1" android: layout_weight= " 1" android: text= " 1" android: textColor= " #000" android: textSize= " 30dp" android: layout_margin= " 5dp" /> < Buttonandroid: layout_width= " 0dp" android: layout_height= " match_parent" android: id= " @+id/button_2" android: layout_weight= " 1" android: text= " 2" android: textColor= " #000" android: textSize= " 30dp" android: layout_margin= " 5dp" /> < Buttonandroid: layout_width= " 0dp" android: layout_height= " match_parent" android: id= " @+id/button_3" android: layout_weight= " 1" android: text= " 3" android: textColor= " #000" android: textSize= " 30dp" android: layout_margin= " 5dp" /> < Buttonandroid: layout_width= " 0dp" android: layout_height= " match_parent" android: id= " @+id/button_minus" android: layout_weight= " 1" android: text= " -" android: background= " #fffaf0" android: textColor= " #000" android: textSize= " 30dp" android: layout_margin= " 5dp" /> </ LinearLayout> < LinearLayoutandroid: layout_width= " match_parent" android: layout_height= " 0dp" android: layout_weight= " 1" android: orientation= " horizontal" android: weightSum= " 4" > < Buttonandroid: layout_width= " 0dp" android: layout_height= " match_parent" android: id= " @+id/button_0" android: layout_weight= " 2" android: text= " 0" android: textColor= " #000" android: textSize= " 30dp" android: layout_margin= " 5dp" /> < Buttonandroid: layout_width= " 0dp" android: layout_height= " match_parent" android: id= " @+id/button_dot" android: layout_weight= " 1" android: text= " ." android: textColor= " #000" android: textSize= " 30dp" android: layout_margin= " 5dp" /> < Buttonandroid: layout_width= " 0dp" android: layout_height= " match_parent" android: id= " @+id/button_result" android: layout_weight= " 1" android: text= " =" android: background= " #ff6347" android: textColor= " #fff" android: textSize= " 30dp" android: layout_margin= " 5dp" /> </ LinearLayout> </ LinearLayout>
布局使用LinearLayout布局,android:orientation="vertical"指定垂直布局,从上至下依次是表达式显示框,结果显示框以及五行按钮,并指定总权重方便控制显示。 文本框TextView使用android:gravity="right|bottom"指定其从右下开始显示内容。 在按钮上,使用android:background="#ff0000"指定按钮背景颜色,使用android:layout_margin="5dp"控制偏移,使其不会过于紧凑。(关于按钮背景颜色无法设置,可在res//values//themes.xml文件下将代码<style name="Theme.Calculation" parent="Theme.MaterialComponents.DayNight.DarkActionBar.">改为<style name="Theme.Calculation" parent="Theme.MaterialComponents.DayNight.DarkActionBar.Bridge">)
二、计算器逻辑设计
package com. example. calculation ; import androidx. appcompat. app. AppCompatActivity ; import android. os. Bundle ;
import android. util. TypedValue ;
import android. view. View ;
import android. widget. Button ;
import android. widget. TextView ; import java. math. BigDecimal ;
import java. util. LinkedList ;
import java. util. Queue ;
import java. util. Stack ; public class MainActivity extends AppCompatActivity implements View. OnClickListener { private final StringBuilder sb = new StringBuilder ( ) ; private String expression = "" ; private String result = "" ; private boolean isHasDot = false ; private final Stack < Boolean > dotStack = new Stack < > ( ) ; private boolean isZero = false ; private final Stack < Boolean > zeroStack = new Stack < > ( ) ; private int leftNum = 0 ; private int rightNum = 0 ; private TextView textView; private TextView result_view; @Override protected void onCreate ( Bundle savedInstanceState) { super . onCreate ( savedInstanceState) ; setContentView ( R . layout. activity_main) ; textView = ( TextView ) findViewById ( R . id. text_view) ; textView. setAutoSizeTextTypeUniformWithConfiguration ( 4 , 70 , 10 , TypedValue . COMPLEX_UNIT_DIP) ; result_view = ( TextView ) findViewById ( R . id. result_view) ; result_view. setAutoSizeTextTypeUniformWithConfiguration ( 4 , 70 , 10 , TypedValue . COMPLEX_UNIT_DIP) ; Button button1 = ( Button ) findViewById ( R . id. button_1) ; button1. setOnClickListener ( this ) ; Button button2 = ( Button ) findViewById ( R . id. button_2) ; button2. setOnClickListener ( this ) ; Button button3 = ( Button ) findViewById ( R . id. button_3) ; button3. setOnClickListener ( this ) ; Button button4 = ( Button ) findViewById ( R . id. button_4) ; button4. setOnClickListener ( this ) ; Button button5 = ( Button ) findViewById ( R . id. button_5) ; button5. setOnClickListener ( this ) ; Button button6 = ( Button ) findViewById ( R . id. button_6) ; button6. setOnClickListener ( this ) ; Button button7 = ( Button ) findViewById ( R . id. button_7) ; button7. setOnClickListener ( this ) ; Button button8 = ( Button ) findViewById ( R . id. button_8) ; button8. setOnClickListener ( this ) ; Button button9 = ( Button ) findViewById ( R . id. button_9) ; button9. setOnClickListener ( this ) ; Button button0 = ( Button ) findViewById ( R . id. button_0) ; button0. setOnClickListener ( this ) ; Button buttondot = ( Button ) findViewById ( R . id. button_dot) ; buttondot. setOnClickListener ( this ) ; Button buttonadd = ( Button ) findViewById ( R . id. button_add) ; buttonadd. setOnClickListener ( this ) ; Button buttonminus = ( Button ) findViewById ( R . id. button_minus) ; buttonminus. setOnClickListener ( this ) ; Button buttonmult = ( Button ) findViewById ( R . id. button_mult) ; buttonmult. setOnClickListener ( this ) ; Button buttondivide = ( Button ) findViewById ( R . id. button_divide) ; buttondivide. setOnClickListener ( this ) ; Button buttonac = ( Button ) findViewById ( R . id. button_ac) ; buttonac. setOnClickListener ( this ) ; Button buttondel = ( Button ) findViewById ( R . id. button_del) ; buttondel. setOnClickListener ( this ) ; Button buttonleft = ( Button ) findViewById ( R . id. button_left) ; buttonleft. setOnClickListener ( this ) ; Button buttonright = ( Button ) findViewById ( R . id. button_right) ; buttonright. setOnClickListener ( this ) ; Button buttonresult = ( Button ) findViewById ( R . id. button_result) ; buttonresult. setOnClickListener ( this ) ; } @Override public void onClick ( View v) { result_view. setText ( "" ) ; switch ( v. getId ( ) ) { case R . id. button_1: if ( isZero == true ) { sb. deleteCharAt ( sb. length ( ) - 1 ) ; isZero = false ; } sb. append ( '1' ) ; textView. setText ( sb. toString ( ) ) ; break ; case R . id. button_2: if ( isZero == true ) { sb. deleteCharAt ( sb. length ( ) - 1 ) ; isZero = false ; } sb. append ( '2' ) ; textView. setText ( sb. toString ( ) ) ; break ; case R . id. button_3: if ( isZero == true ) { sb. deleteCharAt ( sb. length ( ) - 1 ) ; isZero = false ; } sb. append ( '3' ) ; textView. setText ( sb. toString ( ) ) ; break ; case R . id. button_4: if ( isZero == true ) { sb. deleteCharAt ( sb. length ( ) - 1 ) ; isZero = false ; } sb. append ( '4' ) ; textView. setText ( sb. toString ( ) ) ; break ; case R . id. button_5: if ( isZero == true ) { sb. deleteCharAt ( sb. length ( ) - 1 ) ; isZero = false ; } sb. append ( '5' ) ; textView. setText ( sb. toString ( ) ) ; break ; case R . id. button_6: if ( isZero == true ) { sb. deleteCharAt ( sb. length ( ) - 1 ) ; isZero = false ; } sb. append ( '6' ) ; textView. setText ( sb. toString ( ) ) ; break ; case R . id. button_7: if ( isZero == true ) { sb. deleteCharAt ( sb. length ( ) - 1 ) ; isZero = false ; } sb. append ( '7' ) ; textView. setText ( sb. toString ( ) ) ; break ; case R . id. button_8: if ( isZero == true ) { sb. deleteCharAt ( sb. length ( ) - 1 ) ; isZero = false ; } sb. append ( '8' ) ; textView. setText ( sb. toString ( ) ) ; break ; case R . id. button_9: if ( isZero == true ) { sb. deleteCharAt ( sb. length ( ) - 1 ) ; isZero = false ; } sb. append ( '9' ) ; textView. setText ( sb. toString ( ) ) ; break ; case R . id. button_0: if ( isZero == false ) { sb. append ( '0' ) ; if ( sb. length ( ) == 1 || ! ( '0' <= sb. charAt ( sb. length ( ) - 2 ) && sb. charAt ( sb. length ( ) - 2 ) <= '9' ) && sb. charAt ( sb. length ( ) - 2 ) != '.' ) { isZero = true ; } } textView. setText ( sb. toString ( ) ) ; break ; case R . id. button_dot: if ( isHasDot == false ) { if ( sb. length ( ) == 0 || ! ( '0' <= sb. charAt ( sb. length ( ) - 1 ) && sb. charAt ( sb. length ( ) - 1 ) <= '9' ) ) { sb. append ( "0." ) ; } else { sb. append ( '.' ) ; } isHasDot = true ; isZero = false ; } textView. setText ( sb. toString ( ) ) ; break ; case R . id. button_add: if ( sb. length ( ) != 0 && ( sb. charAt ( sb. length ( ) - 1 ) == '+' || sb. charAt ( sb. length ( ) - 1 ) == '-' || sb. charAt ( sb. length ( ) - 1 ) == '*' || sb. charAt ( sb. length ( ) - 1 ) == '/' ) ) { sb. setCharAt ( sb. length ( ) - 1 , '+' ) ; } else if ( sb. length ( ) != 0 ) { sb. append ( '+' ) ; zeroStack. push ( isZero) ; dotStack. push ( isHasDot) ; isZero = false ; isHasDot = false ; } if ( result. matches ( "[-]?\\d+[.]?\\d*" ) && sb. length ( ) == 0 ) { sb. append ( result + "+" ) ; isHasDot = result. matches ( "[-]?\\d*[.]\\d*" ) ; isZero = "0" . equals ( result) ; zeroStack. push ( isZero) ; dotStack. push ( isHasDot) ; isZero = false ; isHasDot = false ; } textView. setText ( sb. toString ( ) ) ; break ; case R . id. button_minus: if ( sb. length ( ) != 0 && ( sb. charAt ( sb. length ( ) - 1 ) == '+' || sb. charAt ( sb. length ( ) - 1 ) == '-' || sb. charAt ( sb. length ( ) - 1 ) == '*' || sb. charAt ( sb. length ( ) - 1 ) == '/' ) ) { sb. append ( '(' ) ; zeroStack. push ( isZero) ; dotStack. push ( isHasDot) ; leftNum++ ; } if ( result. matches ( "[-]?\\d+[.]?\\d*" ) && sb. length ( ) == 0 ) { sb. append ( result + "-" ) ; isHasDot = result. matches ( "[-]?\\d*[.]\\d*" ) ; isZero = "0" . equals ( result) ; zeroStack. push ( isZero) ; dotStack. push ( isHasDot) ; isZero = false ; isHasDot = false ; } sb. append ( '-' ) ; zeroStack. push ( isZero) ; dotStack. push ( isHasDot) ; isZero = false ; isHasDot = false ; textView. setText ( sb. toString ( ) ) ; break ; case R . id. button_mult: if ( sb. length ( ) != 0 && ( sb. charAt ( sb. length ( ) - 1 ) == '+' || sb. charAt ( sb. length ( ) - 1 ) == '-' || sb. charAt ( sb. length ( ) - 1 ) == '*' || sb. charAt ( sb. length ( ) - 1 ) == '/' ) ) { sb. setCharAt ( sb. length ( ) - 1 , '*' ) ; } else if ( sb. length ( ) != 0 ) { sb. append ( '*' ) ; zeroStack. push ( isZero) ; dotStack. push ( isHasDot) ; isZero = false ; isHasDot = false ; } if ( result. matches ( "[-]?\\d+[.]?\\d*" ) && sb. length ( ) == 0 ) { sb. append ( result + "*" ) ; isHasDot = result. matches ( "[-]?\\d*[.]\\d*" ) ; isZero = "0" . equals ( result) ; zeroStack. push ( isZero) ; dotStack. push ( isHasDot) ; isZero = false ; isHasDot = false ; } textView. setText ( sb. toString ( ) ) ; break ; case R . id. button_divide: if ( sb. length ( ) != 0 && ( sb. charAt ( sb. length ( ) - 1 ) == '+' || sb. charAt ( sb. length ( ) - 1 ) == '-' || sb. charAt ( sb. length ( ) - 1 ) == '*' || sb. charAt ( sb. length ( ) - 1 ) == '/' ) ) { sb. setCharAt ( sb. length ( ) - 1 , '/' ) ; } else if ( sb. length ( ) != 0 ) { sb. append ( '/' ) ; zeroStack. push ( isZero) ; dotStack. push ( isHasDot) ; isZero = false ; isHasDot = false ; } if ( result. matches ( "[-]?\\d+[.]?\\d*" ) && sb. length ( ) == 0 ) { sb. append ( result + "/" ) ; isHasDot = result. matches ( "[-]?\\d*[.]\\d*" ) ; isZero = "0" . equals ( result) ; zeroStack. push ( isZero) ; dotStack. push ( isHasDot) ; isZero = false ; isHasDot = false ; } textView. setText ( sb. toString ( ) ) ; break ; case R . id. button_left: sb. append ( '(' ) ; leftNum++ ; zeroStack. push ( isZero) ; dotStack. push ( isHasDot) ; isZero = false ; isHasDot = false ; textView. setText ( sb. toString ( ) ) ; break ; case R . id. button_right: sb. append ( ')' ) ; rightNum++ ; zeroStack. push ( isZero) ; dotStack. push ( isHasDot) ; isZero = false ; isHasDot = false ; textView. setText ( sb. toString ( ) ) ; break ; case R . id. button_del: if ( sb. length ( ) != 0 ) { if ( sb. charAt ( sb. length ( ) - 1 ) == '.' ) { isHasDot = false ; if ( sb. charAt ( sb. length ( ) - 2 ) == '0' ) { sb. deleteCharAt ( sb. length ( ) - 1 ) ; } } if ( sb. charAt ( sb. length ( ) - 1 ) == '(' ) { leftNum-- ; } if ( sb. charAt ( sb. length ( ) - 1 ) == ')' ) { rightNum-- ; } if ( sb. charAt ( sb. length ( ) - 1 ) == '0' && isZero == true ) { isZero = false ; } if ( ! ( sb. charAt ( sb. length ( ) - 1 ) == '.' || '0' <= sb. charAt ( sb. length ( ) - 1 ) && sb. charAt ( sb. length ( ) - 1 ) <= '9' ) ) { if ( ! dotStack. isEmpty ( ) ) { isHasDot = dotStack. pop ( ) ; } if ( ! zeroStack. isEmpty ( ) ) { isZero = zeroStack. pop ( ) ; } } sb. deleteCharAt ( sb. length ( ) - 1 ) ; } result_view. setText ( "" ) ; textView. setText ( sb. toString ( ) ) ; break ; case R . id. button_ac: if ( sb. length ( ) != 0 ) { sb. delete ( 0 , sb. length ( ) ) ; } isHasDot = false ; isZero = false ; zeroStack. clear ( ) ; dotStack. clear ( ) ; expression = "" ; result = "" ; leftNum = 0 ; rightNum = 0 ; result_view. setText ( "" ) ; textView. setText ( "" ) ; break ; case R . id. button_result: if ( sb. length ( ) != 0 ) { textView. setText ( sb. toString ( ) ) ; isHasDot = false ; isZero = false ; zeroStack. clear ( ) ; dotStack. clear ( ) ; if ( leftNum < rightNum) { result = "出错" ; sb. delete ( 0 , sb. length ( ) ) ; result_view. setText ( result) ; leftNum = 0 ; rightNum = 0 ; break ; } else if ( leftNum > rightNum) { while ( leftNum > rightNum) { sb. append ( ')' ) ; rightNum++ ; } } if ( sb. charAt ( 0 ) == '-' ) { sb. insert ( 0 , '0' ) ; } if ( sb. charAt ( sb. length ( ) - 1 ) == '+' || sb. charAt ( sb. length ( ) - 1 ) == '-' ) { sb. append ( '0' ) ; } if ( sb. charAt ( sb. length ( ) - 1 ) == '*' || sb. charAt ( sb. length ( ) - 1 ) == '/' ) { sb. append ( '1' ) ; } for ( int i = 1 ; i < sb. length ( ) - 1 ; i++ ) { char ch = sb. charAt ( i) ; if ( ch == '(' && ( sb. charAt ( i - 1 ) == '.' || '0' <= sb. charAt ( i - 1 ) && sb. charAt ( i - 1 ) <= '9' ) ) { sb. insert ( i, '*' ) ; } if ( ch == ')' && '0' <= sb. charAt ( i + 1 ) && sb. charAt ( i + 1 ) <= '9' ) { sb. insert ( i + 1 , '*' ) ; } } expression = sb. toString ( ) ; sb. delete ( 0 , sb. length ( ) ) ; exchange ( expression) ; expression = "" ; leftNum = 0 ; rightNum = 0 ; } result_view. setText ( result) ; break ; } } public void exchange ( String expression) { Queue < Object > queue = new LinkedList < > ( ) ; Stack < Character > stack = new Stack < > ( ) ; int figureNum = 0 ; int operatorNum = 0 ; StringBuilder numSb = new StringBuilder ( ) ; for ( int i = 0 ; i < expression. length ( ) ; i++ ) { char ch = expression. charAt ( i) ; if ( ch == '.' || ( '0' <= ch && ch <= '9' ) ) { numSb. append ( ch) ; } else { if ( numSb. length ( ) != 0 ) { queue. offer ( new BigDecimal ( numSb. toString ( ) ) ) ; figureNum++ ; numSb. delete ( 0 , numSb. length ( ) ) ; } if ( ch == '-' && expression. charAt ( i - 1 ) == '(' && ( '0' <= expression. charAt ( i + 1 ) && expression. charAt ( i + 1 ) <= '9' ) ) { numSb. append ( ch) ; continue ; } if ( ch == '(' ) { stack. push ( ch) ; } else if ( ( ch == '+' || ch == '-' ) && ! stack. isEmpty ( ) && stack. peek ( ) == '(' ) { stack. push ( ch) ; } else if ( ( ch == '*' || ch == '/' ) && ! stack. isEmpty ( ) && ! ( stack. peek ( ) == '*' || stack. peek ( ) == '/' ) ) { stack. push ( ch) ; } else { while ( ! stack. empty ( ) && stack. peek ( ) != '(' ) { queue. offer ( stack. pop ( ) ) ; operatorNum++ ; } if ( ! stack. isEmpty ( ) ) { stack. pop ( ) ; } if ( ch != ')' ) { stack. push ( ch) ; } } } } if ( numSb. length ( ) != 0 ) { queue. offer ( new BigDecimal ( numSb. toString ( ) ) ) ; figureNum++ ; } while ( ! stack. empty ( ) ) { queue. offer ( stack. pop ( ) ) ; operatorNum++ ; } if ( figureNum == operatorNum + 1 ) { calculate ( queue) ; } else { result = "出错" ; } } public void calculate ( Queue < Object > queue) { Stack < BigDecimal > stack = new Stack < > ( ) ; while ( ! queue. isEmpty ( ) ) { Object obj = queue. poll ( ) ; if ( obj. getClass ( ) == Character . class ) { char operator = ( Character ) obj; BigDecimal num1 = ( BigDecimal ) stack. pop ( ) ; BigDecimal num2 = ( BigDecimal ) stack. pop ( ) ; BigDecimal subResult; if ( operator == '+' ) { subResult = num2. add ( num1) ; stack. push ( subResult) ; } else if ( operator == '-' ) { subResult = num2. subtract ( num1) ; stack. push ( subResult) ; } else if ( operator == '*' ) { subResult = num2. multiply ( num1) ; stack. push ( subResult) ; } else { if ( "0" . equals ( num1. toString ( ) ) ) { result = "不能除以零" ; return ; } else if ( "0" . equals ( num2. toString ( ) ) ) { stack. push ( new BigDecimal ( "0" ) ) ; } else { subResult = num2. divide ( num1, 20 , BigDecimal . ROUND_HALF_UP) ; stack. push ( subResult) ; } } } else { stack. push ( ( BigDecimal ) obj) ; } } result = stack. pop ( ) . toString ( ) ; if ( result. matches ( "[-]?\\d*[.]\\d*" ) ) { int i = result. length ( ) - 1 ; while ( result. charAt ( i) == '0' ) { i-- ; } if ( result. charAt ( i) == '.' ) { i-- ; } result = result. substring ( 0 , i + 1 ) ; } }
}
expression,result,textview等会多次使用,因此将其设置为成员变量。 显示框根据行数自动放大或缩小。使用textView.setAutoSizeTextTypeUniformWithConfiguration(4, 70, 10, TypedValue.COMPLEX_UNIT_DIP);方法控制。第一个参数表示最小大小,第二个参数表示最大大小,第三个参数表示每次缩小步长,第四个参数表示之前参数的单位(如:dp,sp等)。
除了按下等号键显示计算结果,其余按键都不需要显示,因此将结果显示框设为空。 输入数字时,如果前一个是数字“0”,按下其他数字应显示该数字,即显示“1”而不是“01”。 按下加减运算符时,如果之前有计算结果,应直接使用该结果运算。 表达式优化:以“-”号开头的表达式,可以在前加上零方便计算;如果左括号少于右括号,此表达式无法计算;左括号少于右括号,可以在末尾补全右括号;表达式以“+”“-”号结尾,应补上0,以“*”“/”结尾,应补上1;对于a(b),(a)b应自动补上乘号
遇到数字以及小数点直接保存,遇到符号按照优先级顺序出栈入栈。 使用计数器分别记录运算符和数字的个数,如果不匹配,直接显示出错
在除法运算中,“0/a”应直接显示0、“a/0”应不计算,直接显示不能除以零 在最后结果上,“2.000000…”的类似有末尾0的结果应去除末尾0以及小数点