『Flutter』项目实战(苹果计算器)处理计算逻辑

1.前言

经过上一篇文章的介绍,已经完成了项目的输入数据,接下来就是处理计算逻辑了。

2.计算逻辑 AC、+/-、%

首先实现 AC+/-%,先定义需要使用的变量:

代码语言:js
复制
// 保存前面输入数据
dynamic _num1 = 0;
// 保存后面输入数据
dynamic _num2 = 0;
// 保存当前计算状态
bool isCalculate = false;

然后实现 AC+/-% 的点击事件:

AC

代码语言:js
复制
_output = "0";
_num1 = 0;
_num2 = 0;
isCalculate = false;

+/-

代码语言:js
复制
// 负负得正
if (_output.contains(".")){
  // 小数
  _output = (-double.parse(_output)).toString();
} else {
  // 整数
  _output = (-int.parse(_output)).toString();
}

%, 在实现 % 之前给大家介绍一下在 Flutter 中如何安装第三方库,因为这里我需要使用到一个第三方库来解决精度问题,所以需要先安装:

在 Flutter 中安装第三方库通常涉及以下几个步骤:

  1. 找到库: 访问 pub.dev(官方的 Flutter 和 Dart 包管理网站),并找到你需要的库。库页面将提供安装指令、文档和使用示例。
  2. 更新 pubspec.yaml 文件: 在你的 Flutter 项目根目录中找到 pubspec.yaml 文件。在 dependencies 部分添加你想要安装的库及其版本。例如,如果你想安装一个名为 http 的库,你会这样做:
代码语言:yaml
复制
dependencies:
  flutter:
    sdk: flutter
  # 添加这行,版本号可能不同
  http: ^0.13.3

安装库: 打开终端(或命令提示符、或IDE的终端),导航到你的项目目录,然后运行以下命令以获取和安装新的依赖:

代码语言:shell
复制
flutter pub get

在项目中使用库: 在你的 Dart 代码中,现在你可以引用并使用这个库了。通常,你需要导入包含你需要的功能的特定文件。例如,如果你安装了 http 库,你可能需要这样做:

代码语言:js
复制
import 'package:http/http.dart' as http;

查看文档和示例: 返回到你在 pub.dev 上找到的库页面,阅读文档和查看示例代码以了解如何使用这个库。

确保遵循库的官方文档,因为不同的库可能有特定的安装步骤或依赖要求。

我这里使用 decimal

%

安装 decimal

代码语言:shell
复制
flutter pub get

导入与定义 decimal

代码语言:js
复制
// 引入解决丢失精度库
import 'package:decimal/decimal.dart';
代码语言:js
复制
// 快速处理丢失精度结构
final d = (String s) => Decimal.parse(s);
代码语言:js
复制
// 百分号, 除以100
_output = (d(_output) / d("100.0")).toDouble().toString();

查看一波效果:

3.计算逻辑 +、-、x、÷、=

在定义一个变量用于保存当前运算符 _operand

代码语言:js
复制
// 保存当前运算符
String _operand = "";

然后实现 +-x÷= 的点击事件:

+-x÷

代码语言:js
复制
case "÷":
  isCalculate = true;
  _operand = btnText;

// 如果已经保存了上一次输入内容, 那么就做运算
if (_num1 != 0) {
// 小数之间的运算
if (_output.contains(".") || _num1 is double) {
// 保存当前输入值
_num2 = double.parse(_output);
_output = (d(_num1.toString()) / d(_num2.toString()))
.toDouble()
.toString();
_num1 = double.parse(_output);
} else {
// 整数之间运算
_num2 = double.parse(_output);
// 保存当前输入值
_output = (d(_num1.toString()) / d(_num2.toString()))
.toBigInt()
.toString();
_num1 = int.parse(_output);
}
}
break;
case "x":
isCalculate = true;
_operand = btnText;
// 如果已经保存了上一次输入内容, 那么就做运算
if (_num1 != 0) {
// 小数之间的运算
if (_output.contains(".") || _num1 is double) {
// 保存当前输入值
_num2 = double.parse(_output);
_output = (d(_num1.toString()) * d(_num2.toString()))
.toDouble()
.toString();
_num1 = double.parse(_output);
} else {
// 整数之间运算
// 保存当前输入值
_num2 = double.parse(_output);
_output = (d(_num1.toString()) * d(_num2.toString()))
.toBigInt()
.toString();
_num1 = int.parse(_output);
}
}
break;
case "+":
isCalculate = true;
_operand = btnText;
if (_num1 != 0) {
// 如果已经保存了上一次输入内容, 那么就做运算
if (_output.contains(".") || _num1 is double) {
// 小数之间的运算
// 保存当前输入值
_num2 = double.parse(_output);
_output = (d(_num1.toString()) + d(_num2.toString()))
.toDouble()
.toString();
_num1 = double.parse(_output);
} else {
// 整数之间运算
// 保存当前输入值
_num2 = double.parse(_output);
_output = (d(_num1.toString()) + d(_num2.toString()))
.toBigInt()
.toString();
_num1 = int.parse(_output);
}
}
break;
case "-":
isCalculate = true;
_operand = btnText;
if (_num1 != 0) {
// 如果已经保存了上一次输入内容, 那么就做运算
if (_output.contains(".") || _num1 is double) {
// 小数之间的运算
// 保存当前输入值
_num2 = double.parse(_output);
_output = (d(_num1.toString()) - d(_num2.toString()))
.toDouble()
.toString();
_num1 = double.parse(_output);
} else {
// 整数之间运算
// 保存当前输入值
_num2 = double.parse(_output);
_output = (d(_num1.toString()) - d(_num2.toString()))
.toBigInt()
.toString();
_num1 = int.parse(_output);
}
}
break;
case "=":
onBtnClick(_operand);
_operand = "";
isCalculate = false;
_num1 = 0;
_num2 = 0;
break;

default 里面的逻辑,还需要改动一下:

代码语言:js
复制
// 判断是否点击了运算符, 如果点击了就将当前的数据先存储起来
if (isCalculate) {
if (_output.contains(".")) {
_num1 = double.parse(_output);
} else {
_num1 = int.parse(_output);
}
_output = "0";
isCalculate = false;
}

AC 需要在加一句清空当前运算符的代码:

代码语言:js
复制
_operand = "";

好,代码写完了,我主要解释下 除法= 的逻辑, 然后其它的就是类似的了。

实现 + 的逻辑, 首先要将 isCalculate 设置为 true, 然后将当前的运算符保存到 _operand 中,然后判断 _num1 是否为 0,如果不为 0,说明已经保存了上一次输入的数据,那么就做运算,如果为 0,说明是第一次输入,那么就不做运算。

然后判断 _output 是否包含小数点,如果包含小数点,说明是小数,那么就将 _num1_num2 都转换为 double 类型,然后做除法运算,最后将结果转换为 String 类型,然后将 _num1 保存为当前的结果。

如果不包含小数点,说明是整数,那么就将 _num1_num2 都转换为 int 类型,然后做除法运算,最后将结果转换为 String 类型,然后将 _num1 保存为当前的结果。

实现 = 的逻辑,首先调用 onBtnClick 方法,将当前的运算符传递进去,然后将 _operand 设置为空,将 isCalculate 设置为 false,将 _num1_num2 设置为 0。

最后的效果:

代码中有可优化的代码,我就不优化了,大家可以自行优化。

End

🐤如果您对本文有任何疑问或想法,请在评论区留言,我将很乐意与您交流。
🐰您的每一条评论对我都至关重要,我会尽快给予回复。
🎈如果您觉得这篇文章对您有所启发或帮助,请不吝赞赏、收藏或分享。
🎁您的每一个动作都是对我创作的最大鼓励和支持。
👍谢谢您的阅读和陪伴!
😁如果您觉得本文对您有所帮助,可以关注我的公众号 杨不易呀,我会不定期分享一些干货文章。
🍻感谢您的支持,我会继续努力的!