前言:

计算器作为日常生活中经常使用的工具,早已植入我们的手机,并成为了一个必不可少的应用。随着技术的更新,现在手机上的计算器不在满足于以前简单的加、减、乘、除运算功能。本应用基于 Android5.0 原生 Calculator,增加了复制、粘贴,保存历史功能。在本文中,我们将从应用的总体设计、UI 介绍、类结构,以及其具体功能等方面分别介绍。

一、总体设计

根据 MVC 设计模式,将此应用分为如下三层。各层之间的关系如下图所示:

coildesigner计算方法_自定义控件

(一)View 层
负责接收用户输入,将用户的输入传给 Controller 层,Controller 接收用户输入返回要显示的数据。

(二)Controller 层
负责接收 View 传来的输入,根据序列特征进行解析(是否根据优先级计算某部分中间结果,是否是异常的不该回显的符号,是否是非法表达式等)。解析后的序列交给 Module 层计算并等待其返回,最后将要回显的字符序列回传给View 层。

(三)Module 层
负责接收来自 Controller 的计算任务,并将结果返回给 Controller 层。


二、架构图

coildesigner计算方法_coildesigner计算方法_02


三、UI 介绍

(一)显示模块

coildesigner计算方法_coildesigner计算方法_03

图一说明:
第一次进入 Calculator 的时候会首先进入 Splash 页面,这个界面如图一所示。整个布局是一个 RelativeLayout。
1.红色区域为一对 RelativeLayout,分别包含两个 ImageView 和一个TextView,形成动画循环显示。

2.蓝色区域为一个 LinearLayout,包含两个 Button,跟随红色区域动画效果进行白色圆点位置的切换。
3.绿色区域是一个单独的 Button,点击“GOT IT”即进入 Calculator 主界面。

图二说明:
图 二 是 Calculator 主 界 面 的 竖 屏 样 式 , 整 体 的 布 局 是 在activity_calculator_port.xml 中定义的。
1.红色区域为 Calculator 的输入模块。整个控件为 DisplayOverlay 自定义控件,继承于 FramLayout,主要用来管理“历史”滑动操作,在 display.xml中定义。
2.蓝色区域为自定义控件 MyRecyclerView,继承于 RecyclerView,主要用来记录运算历史记录。
3.粉色区域为 2 个 CalculatorEditText 自定义控件,继承于 EditText,用于显示公式和计算结果。


(二)输入模块

coildesigner计算方法_xml_04

图三,图四中绿色区域对应 Calculator 的输入模块,整个布局是个CalculatorPadViewPager 自定义控件,继承于 ViewPager,分为三块。
1.蓝色区域为数字按键,在 pad_numeric.xml 中定义。
2.粉色区域为运算符按键,在 pad_operator_one_col.xml 中定义。
3.红色区域在 pad_advanced.xml,主要是科学计算符的 page。
以上三区域都被定义于自定义控件 CalculatorPadLayout 中,该控件继承于ViewGroup,用于摆放控件。
横屏时的布局如图五:

coildesigner计算方法_剪切板_05

横屏的整个布局为 activity_calculator_land.xml。
1.蓝色区域为数字按键,在 pad_numeric.xml 中定义。
2.粉色区域为运算符按键,在 pad_operator_one_col.xml 中定义。
3.红色区域在 pad_advanced.xml,主要是科学计算符的 page。


四、类的介绍

一)类结构总览
Calculator 的主要类,如下所示:

coildesigner计算方法_coildesigner计算方法_06

(二)原生类
原生类:Android 5.0 原生 Calculator 包含的类

coildesigner计算方法_xml_07


(三)新增类
新增类:基于 Android 5.0 原生 Calculator 额外新增的类

coildesigner计算方法_coildesigner计算方法_08


五、Calculator 功能
该应用是基于 Android5.0 原生 Calculator 设计,在原有计算功能基础上增加了“保存计算历史”,“复制、粘贴”的功能


(一)运算功能

coildesigner计算方法_自定义控件_09

点击 CalculatorPadView 里面的按键,将 Button 上的字符串根据逻辑显示给 FromulaView;FromulaView 根据 textwatcher 监听字符串的改变,调用CalculatorExpressionEvaluator 的 evaluate 方 法 进 行 运 算 , 在CalculatorExpressionEvaluator 的 evaluate 方 法 中 , 会 调 用CalculatorExpressionTokenizer 的方法对 FormulaView 中的表达式进行逻辑判断,最后将此表达式交给第三方库 arity.2.1.2.jar 进行运算,运算后将结果显示 给 ResultView 。 当 用户 点 击 “=”则 ResultView 清 空 ,将 结 果 显 示于FormulaView。
注:核心算法是封装在三方提供的 arity.2.1.2.jar 中.
具体如下:


coildesigner计算方法_xml_10


(二)下拉显示历史

coildesigner计算方法_xml_11


通过上面的运算,我们已经在数据库里面保存了最近 10 次内的运算记录,可以通过点击 DisplayOverlay 下拉显示出来。
类图如下 :

coildesigner计算方法_剪切板_12

这里通过 HistoryAdapter 将数据设置给 SQLite。 下拉时通过查询数据库将内容设置给 HistoryAdapter,最终呈现在 MyRecycleView 上。

(三)复制/粘贴
1.长按历史面板复制流程

coildesigner计算方法_xml_13

如下图:

coildesigner计算方法_coildesigner计算方法_14


长按复制/粘贴功能是作用在 FromulaView 以及 ResultView 上,这个功能是在 Andoird5.0 原生 Calculator 基础上新加的一个功能。 主要是做复制粘贴的逻辑判断然后调用系统剪切板方法 setPrimaryClip(),getPrimaryClip() 以及判断方法 hasPrimaryClip()。

2.公式与结果栏复制/粘贴流程
注:1.公式栏有复制和粘贴功能,结果栏只有复制功能。
2.INPUT 状态:即输入公式未到 RESULT,如下图:

RESULT 状态:即计算得出结果(非 ERROR 状态),如下图:

ERROR 状态:即计算出错时的状态,如下图:


(1)直接复制结果流程

coildesigner计算方法_剪切板_15

当状态是 RESULT 的时候,如果系统剪切板包含有效值,显示 COPY 和 PASTE
按钮。
如果系统剪切板无有效值,就直接显示 Toast 提示,“COPY 完成”。


(2)允许复制流程

coildesigner计算方法_xml_16

当计算状态为 RESULT 时,formula 面板有值,则显示 COPY 按钮,反之隐藏。
当计算状态不为 ERROR 时,result 面板有值,则显示 COPY 按钮,反之隐藏。

(3)允许粘贴流程

coildesigner计算方法_xml_17

当计算状态为 INPUT、ERROR、RESULT 时,系统剪切板包含有效内容,显示
PASTE 按钮,反之隐藏。

六、数据储存

该应用所涉及的数据库表

coildesigner计算方法_xml_18


七、时序图

coildesigner计算方法_xml_19