android GradLayout实现计算器
主界面
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/root" android:layout_width="match_parent" android:layout_height="match_parent" android:columnCount="4" android:rowCount="6" tools:context="com.ssln.gridlayoutcalc.MainActivity" > <TextView android:id="@+id/tvResult" android:layout_column="0" android:layout_columnSpan="4" android:layout_row="0" android:background="#eee" android:lines="1" android:minLines="1" android:textColor="#000" android:padding="5dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="50sp" /> <Button android:id="@+id/btnClear" android:layout_columnSpan="4" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="清除" /> </GridLayout>
main.java
package com.ssln.gridlayoutcalc; import android.app.Activity; import android.os.Bundle; import android.view.Gravity; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.GridLayout; import android.widget.TextView; public class MainActivity extends Activity implements OnClickListener{ private GridLayout gridLayout; private Button btnClear; private TextView tvResult; private String[] btns=new String[]{ "7","8","9","/", "4","5","6","x", "1","2","3","-", ".","0","=","+" }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gridLayout=(GridLayout)findViewById(R.id.root); btnClear=(Button)findViewById(R.id.btnClear); tvResult=(TextView)findViewById(R.id.tvResult); btnClear.setOnClickListener(this); for (int i = 0; i < btns.length; i++) { Button btn=new Button(this); btn.setText(btns[i]); btn.setTextSize(40); //设置所在行,+2是因为上面有两行了,一行显示一行按钮 GridLayout.Spec rowSpec=GridLayout.spec(i/4+2); //设置第几列 GridLayout.Spec colSpec=GridLayout.spec(i%4); GridLayout.LayoutParams params=new GridLayout.LayoutParams(rowSpec,colSpec); //占满父容器 params.setGravity(Gravity.FILL); btn.setOnClickListener(this); gridLayout.addView(btn,params); } } @Override public void onClick(View v) { if(v==btnClear) { tvResult.setText(""); } else { String btnText=((Button)v).getText().toString(); tvResult.setText(tvResult.getText().toString()+btnText); if(btnText.equals("=")) { Calc calc=new Calc(tvResult.getText().toString()); String[] Rpn=calc.expToRpn().split(","); double dbResult=calc.CalcRpn(Rpn); tvResult.setText(String.valueOf(dbResult)); } } } }
逆波兰算法
package com.ssln.gridlayoutcalc; import java.util.HashMap; import java.util.Map; import java.util.Stack; /** * 逆波兰式 Reverse Polish Notation * @author xcj * */ public class Calc { //操作数 private Stack<Double> calcStack=new Stack<Double>(); //操作符 private Stack<String> operatorStack=new Stack<String>(); //操作符优先级 private Map<String,Integer> priorityMap=new HashMap<String,Integer>(); private String Expression;//计算表达式 private Double calcResult=0.0d; //计算结果 public Calc(String exp) { Expression=exp; priorityMap.put("+", 0); priorityMap.put("-", 0); priorityMap.put("x", 1); priorityMap.put("/", 1); } /** * 获取操作符优先级 * @param operator * @return */ public int getPriority(String operator) { return priorityMap.get(operator); } /** * 判断是否最高优先级 * @param operator * @return */ public boolean isHighpriority(String operator) { int operPrio=getPriority(operator); //获取优先级 if(!operatorStack.empty()) { for (String str : operatorStack) { int currPrio=getPriority(str); if(operPrio<currPrio) return false; } } return true; } /** * 表达式转换为逆波兰 * @return */ public String expToRpn(){ int index=0,end=0; String Rpn=""; for (int i = 0; i < Expression.length(); i++) { String tmp=String.valueOf(Expression.charAt(i)); //如果是数字,就把结束符加1 if(tmp.matches("[0-9.]")) { end++; } else { //获取得到的操作数 String calcStr=Expression.substring(index,end); Rpn+=calcStr+","; //加入操作数 //取得操作符 int endx=end+1; String calcOper=Expression.substring(end,endx); end++; if(calcOper.equals("="))//如果要计算结果了 { while(!operatorStack.empty()) { //将所有的操作符放入RpN Rpn+=operatorStack.pop()+","; } } else { if(isHighpriority(calcOper)) { //如果优先级较高,压入堆栈 operatorStack.push(calcOper); } else { //如果不是最高的,将最高的放到前面 while(!operatorStack.empty()) { Rpn+=operatorStack.pop()+","; } operatorStack.push(calcOper); } index=end; } } } return Rpn; } /** * 根据逆波兰计算 * @param Rpn * @return */ public double CalcRpn(String[] Rpn) { for (int i = 0; i < Rpn.length; i++) { String str = Rpn[i]; if(str.matches("^[0-9]+.?[0-9]*$")) { //如果是数字,压入操作数堆栈 calcStack.push(Double.parseDouble(str)); } else { //计算数值 CalcOperator(str); } } return calcResult; } /** * 计算数值 * @param operator */ private void CalcOperator(String operator) { double d1=calcStack.pop(); double d2=calcStack.pop(); if(operator.equals("+")) calcResult=d2+d1; if(operator.equals("-")) calcResult=d2-d1; if(operator.equals("x")) calcResult=d2*d1; if(operator.equals("/")) calcResult=d2/d1; //结果再次放入栈 calcStack.push(calcResult); } public String getExpression() { return Expression; } public void setExpression(String expression) { Expression = expression; } }
效果,用自制的GIF动画录制录制的