Android计算器学习

Android Studio 2.3.2 。参考文章:http://blog.csdn.net/like_program/article/details/51813632

1. 新建工程 MyCalculator,一路下一步,均采用默认值。

2. 按照要求修改三个xml文件内容。很多地方工程名字不一样,改成自己的名字。

3. 按照步骤修改Activity_main.XML文件,遇到问题:

android:singleLine="false" 过时

暂时处理方式:删掉此行。

4. 按照步骤依次加入代码,计算器可以正常运行。

5. 原文作者写的注释非常详细,计划认真阅读后,自己做一遍。

6. 未增加美化部分,留作后面的内容学习。http://blog.csdn.net/like_program/article/details/51925765

 

 

MainActivity.java

 

  1 package com.example.mycalculator;
  2 
  3 import android.os.Bundle;
  4 import android.support.v7.app.AppCompatActivity;
  5 import android.text.Html;
  6 import android.view.View;
  7 import android.view.Window;
  8 import android.widget.AdapterView;
  9 import android.widget.AdapterView.OnItemClickListener;
 10 import android.widget.ArrayAdapter;
 11 import android.widget.EditText;
 12 import android.widget.GridView;
 13 
 14 import java.util.ArrayList;
 15 import java.util.List;
 16 
 17 import cn.skw.calculator.Calculator;
 18 
 19 public class MainActivity extends AppCompatActivity {
 20 
 21     /**
 22      * 操作按钮
 23      */
 24     private GridView mGridView = null;
 25 
 26     /**
 27      * 输入框
 28      */
 29     private EditText mEditInput = null;
 30 
 31     /**
 32      * 适配器
 33      */
 34     private ArrayAdapter mAdapter = null;
 35 
 36     /**
 37      * 已计算的表达式
 38      */
 39     private String mPreStr = "";
 40 
 41     /**
 42      * 待计算的表达式
 43      */
 44     private String mLastStr = "";
 45 
 46     /**
 47      * 计算结果
 48      */
 49     private Object mResult = null;
 50 
 51     /**
 52      * 判断刚刚是否成功执行完一个表达式
 53      * 以为,刚加一个表达式时,需要在原来的表达式后面加上换行标签
 54      */
 55     private boolean mIsExecuteNow = false;
 56 
 57     /**
 58      * 换行符
 59      */
 60     private final String newLine = "<br>";
 61 
 62     /**
 63      * 操作按钮上的字符集合
 64      */
 65     private final String[] mTextBtns = new String[]{
 66             "Back","(",")","CE",
 67             "7","8","9","/",
 68             "4","5","6","*",
 69             "1","2","3","+",
 70             "0",".","=","-",
 71     };
 72 
 73     /**
 74      * 用来存储操作按钮上的字符集合
 75      */
 76     private List<String> mTextBtnsList = new ArrayList<String>();
 77 
 78     @Override
 79     protected void onCreate(Bundle savedInstanceState) {
 80         super.onCreate(savedInstanceState);
 81         // 隐藏标题栏
 82         requestWindowFeature(Window.FEATURE_NO_TITLE);
 83         setContentView(R.layout.activity_main);
 84 
 85         initTextBtns();
 86 
 87         mEditInput = (EditText) findViewById(R.id.edit_input);
 88         mGridView = (GridView) findViewById(R.id.grid_buttons);
 89         // 创建适配器
 90         mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mTextBtns);
 91        // mAdapter = new CalculatorAdapter(this, R.id.text_button, mTextBtnsList);
 92         // 设置适配器
 93         mGridView.setAdapter(mAdapter);
 94 
 95         // 禁止EditText从键盘输入
 96         mEditInput.setKeyListener(null);
 97         // 为操作按钮设置按键监听
 98         mGridView.setOnItemClickListener(new OnButtonItemClickListener());
 99     }
100 
101     /**
102      * 这个函数用于设置EditText的显示内容,主要是为了加上html标签.
103      * 所有的显示EditText内容都需要调用此函数
104      */
105     private void setText() {
106         final String[] tags = new String[]{
107                 "<font color='#858585'>",
108                 "<font color='#CD2626'>",
109                 "</font> "
110         };
111         StringBuilder builder = new StringBuilder();
112         // 添加颜色标签
113         builder.append(tags[0]).append(mPreStr).append(tags[2]);
114         builder.append(tags[1]).append(mLastStr).append(tags[2]);
115         // 显示内容
116         mEditInput.setText(Html.fromHtml(builder.toString()));
117         // 设置光标在EditText的最后位置
118         mEditInput.setSelection(mEditInput.getText().length());
119     }
120 
121     /**
122      * 执行 待计算表达式,当用户按下 = 号时,调用这个方法
123      */
124     private void executeExpression() {
125         try {
126             // 调用第三方jar包来执行运算
127             mResult = Calculator.execute(mLastStr);
128             /**
129              * 将计算得到的结果进行处理,
130              * 若结果的小数点后有4位以上,就只保留4位小数
131              * 否则不做处理
132              */
133             mResult = covertNumber(mResult);
134         } catch (Exception e) {
135             /**
136              * 如果捕获到异常,表示表达式执行失败,
137              * 这里设置为false是因为并没有执行成功,还不能新的表达式求值
138              */
139             mIsExecuteNow = false;
140             return;
141         }
142         /**
143          * 若计算结果成功,把 "=" 和 结果 加到待计算表达式,
144          * 更新视图,
145          * 设置标识为true
146          */
147         mLastStr += "="+ mResult;
148         setText();
149         mIsExecuteNow = true;
150     }
151 
152     /**
153      * 先把计算的结果转换为 float ,再把结果进行四舍五入,然后看能不能被1整除,
154      * 如果能整除,说明结果是个 float 类型的整数,将结果转换为 int 类型返回
155      * 如果不能,说明结果是个小数,直接将结果返回
156      *
157      * @param number 结果
158      * @return 处理后的结果
159      */
160     private Object covertNumber(Object number) {
161         /**
162          * 将传入的结果先转换为 string 类型,再转换为 float 类型,赋值给 resultFloat
163          * 这里将 result 转换为 float 类型是因为 float 类型参数是有小数点的,
164          * 而结果(number)先假设也是有小数点,这样 resultFloat 可以完全接受结果(number)而不损失精度
165          */
166         float resultFloat = Float.valueOf(number.toString());
167         /**
168          * 将 resultFloat 先乘10000,然后调用Math.round()方法,进行四舍五入,再除以10000,就把 resultFloat 四舍五入了
169          */
170         resultFloat = (float) (Math.round(resultFloat * 10000)) / 10000;
171         if (resultFloat % 1 == 0) {
172             return (int)resultFloat;
173         } else {
174             return resultFloat;
175         }
176     }
177 
178     /**
179      * 把字符集合依次添加到List中
180      */
181     private void initTextBtns() {
182         for (String btn : mTextBtns) {
183             mTextBtnsList.add(btn);
184         }
185     }
186 
187     private class OnButtonItemClickListener implements OnItemClickListener {
188         @Override
189         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
190             String text = (String) parent.getAdapter().getItem(position);
191             if (text.equals("=")) {
192                 // 执行运算
193                 executeExpression();
194             } else if (text.equals("Back")) {
195                 /**
196                  * 如果按下退格键,表示删除一个字符
197                  * 如果待计算表达式长度为0,则需要把已计算表达式的最后
198                  * 部分赋值给待计算表达式
199                  *
200                  * 例如:
201                  *
202                  * 已计算表达式:1+1=2
203                  * 待计算表达式:空
204                  *
205                  * 按下Back键后:
206                  *
207                  * 已计算表达式:空
208                  * 待计算表达式:1+1=2
209                  *
210                  */
211                 if (mLastStr.length() == 0) {
212                     /**
213                      * 如果已计算表达式的长度不是0,那么此时
214                      * 已计算表达式必然以换行符结尾
215                      */
216                     if (mPreStr.length() != 0) {
217                         // 清除已计算表达式末尾的换行符
218                         mPreStr = mPreStr.substring(0, mPreStr.length() - newLine.length());
219                         // 找到前一个换行符的位置
220                         int index = mPreStr.lastIndexOf(newLine);
221                         if (index == -1) {
222                             /**
223                              * -1表示没有找到,即 已计算表达式只有一个
224                              * 此时把 仅有的一个已计算表达式赋值给待计算表达式
225                              *
226                              * 例如:
227                              *
228                              * 已计算表达式:1+1=2
229                              * 待计算表达式:空
230                              *
231                              * 按下Back键后:
232                              *
233                              * 已计算表达式:空
234                              * 待计算表达式:1+1=2
235                              */
236                             mLastStr = mPreStr;
237                             // 已计算表达式赋值为空
238                             mPreStr = "";
239                         } else {
240                             /**
241                              * 如果找到前一个换行符,即 已计算表达式数量 > 1
242                              * 此时把已计算表达式的最后一个表达式赋值给 待计算表达式
243                              *
244                              * 例如:
245                              *
246                              * 已计算表达式:1+1=2
247                              *              2+2=4
248                              * 待计算表达式:空
249                              *
250                              * 按下Back键后:
251                              *
252                              * 已计算表达式:1+1=2
253                              * 待计算表达式:2+2=4
254                              */
255                             mLastStr = mPreStr.substring(index + newLine.length(), mPreStr.length());
256                             mPreStr = mPreStr.substring(0, index + newLine.length());
257                         }
258                         mIsExecuteNow = true;
259                     }
260                 } else {
261                     // 如果待计算表达式长度不是0,则直接减掉一个字符
262                     mLastStr = mLastStr.substring(0, mLastStr.length() - 1);
263                 }
264                 // 更新视图
265                 setText();
266             } else if (text.equals("CE")) {
267                 /**
268                  * 如果按下 清除键,就把
269                  * 待计算表达式 和 已计算表达式 全部清空,
270                  * 显示内容全部清空,
271                  * 并设置标识符为false
272                  *
273                  * 这里需要注意下,
274                  * 待计算表达式 和 已计算表达式 全部清空,
275                  * 并不代表显示内容就清空了。同样,
276                  * 显示内容清空,也不代表 待计算表达式 和 已计算表达式 全部清空。
277                  */
278                 mPreStr = "";
279                 mLastStr = "";
280                 mIsExecuteNow = false;
281                 mEditInput.setText("");
282             } else {
283                 // 按下其他键的情况
284                 if (mIsExecuteNow) {
285                     /**
286                      * 如果刚刚成功执行了一个表达式,
287                      * 那么需要把  待计算表达式  加到  已计算表达式 后面并添加换行符
288                      *
289                      * 例如:
290                      * 已计算表达式:空
291                      * 待计算表达式:1+1=2
292                      *
293                      * 按下 1 键后:
294                      *
295                      * 已计算表达式:1+1=2
296                      * 待计算表达式:1
297                      *
298                      */
299                     mPreStr += mLastStr + newLine;
300                     // 重置标识为false
301                     mIsExecuteNow = false;
302                     /**
303                      * 如果按下的键是 + - * / 中的任何一个,
304                      * 就把刚刚计算完毕的表达式的结果拿过来,
305                      * 放在待计算表达式的开头
306                      *
307                      * 例如:
308                      * 已计算表达式:1+1=2
309                      * 待计算表达式:空
310                      *
311                      * 按下 + 键后:
312                      *
313                      * 已计算表达式:1+1=2
314                      * 待计算表达式:2+
315                      */
316                     if (text.equals("+") || text.equals("-") || text.equals("*") || text.equals("/")) {
317                         mLastStr = mResult + text;
318                     } else {
319                         // 设置待计算表达式的第一个字符为当前按钮按下的内容
320                         mLastStr = text;
321                     }
322                 } else {
323                     // 否则直接在待计算表达式后面添加内容就好了
324                     mLastStr += text;
325                 }
326                 // 更新视图
327                 setText();
328             }
329         }
330     }
331 }

 

activity_main.xml

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:tools="http://schemas.android.com/tools"
 4     android:layout_width="match_parent"
 5     android:layout_height="match_parent"
 6     android:orientation="vertical"
 7     tools:context="com.example.mycalculator.MainActivity" >
 8 
 9     <!-- 标题 -->
10     <TextView
11         android:layout_width="match_parent"
12         android:layout_height="50dp"
13         android:text="@string/app_name"
14         android:textSize="18sp"
15         android:gravity="center"
16         android:background="@color/colorBlue" />
17 
18     <RelativeLayout
19         android:layout_width="match_parent"
20         android:layout_height="match_parent">
21 
22         <!--操作界面-->
23         <GridView
24             android:id="@+id/grid_buttons"
25             android:layout_width="match_parent"
26             android:layout_height="wrap_content"
27             android:layout_alignParentBottom="true"
28             android:layout_margin="10dip"
29             android:gravity="center"
30             android:horizontalSpacing="10dp"
31             android:numColumns="4"
32             android:verticalSpacing="10dp"></GridView>
33 
34         <!-- 显示界面 -->
35         <EditText
36             android:id="@+id/edit_input"
37             android:layout_width="match_parent"
38             android:layout_height="match_parent"
39             android:layout_above="@id/grid_buttons"
40             android:layout_alignParentTop="true"
41             android:gravity="start"
42             android:hint="@string/hint_text"
43             android:padding="10dp"
44 
45             android:textSize="22sp" />
46 
47     </RelativeLayout>
48 
49 </LinearLayout>

 

colors.xml

 

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
    <color name="colorBlue">#729FFA</color>
    <color name="colorWhite">#FFFFFF</color>
</resources>

 

 

strings.xml

 

<resources>
<string name="app_name">计算器</string>
<string name="hint_text">输入表达式</string>
</resources>

 

 

styles.xml

 

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>

 

 

 

 

 





posted on 2017-06-07 22:05  HBU_DAVID  阅读(334)  评论(0编辑  收藏  举报

导航