『Flutter』项目实战(苹果计算器)处理输入数据

1.前言

经过上一篇文章的介绍,已经完成了项目的页面布局,接下来就是处理输入数据了。

2.处理输入数据

通过上一篇文章中,我编写了一个 buildButton 方法,用于构建按钮,这个方法中有一个 onTap 方法,用于处理按钮的点击事件,所以每个按钮的点击事件都会调用这个方法,接下来就要在这个方法中处理输入数据了。

如果代码都写在 onTap 方法中,那么代码会非常的冗余,所以我将代码抽取出来,封装成一个方法,这个方法的作用就是处理输入数据,代码如下:

代码语言:js
复制
/// Flutter 程序的入口文件
import 'package:flutter/material.dart';

/// Flutter 程序的入口函数
void main() {
// 1.Flutter 主函数,程序一运行起来就会执行
// 2.运行 App 并且创建组件
runApp(const MyApp());
}

接着定义展示组件 Body

代码语言:js
复制
/// MyApp 是一个组件,继承自 StatelessWidget,是一个无状态的组件
/// 并且是符合 Material Design 规范的组件
class MyApp extends StatelessWidget {
/// const 关键字表示 MyApp 是一个常量,一旦创建就不会被修改
/// super.key 表示调用父类的构造函数
const MyApp({super.key});

/// 自定义无状态组件必须重写父类的 build 方法,返回我们构建好的组件
@override
Widget build(BuildContext context) {
// MaterialApp 是一个符合 Material Design 规范的组件
return MaterialApp(
theme: ThemeData.dark(),
// Scaffold 是一个组件,用于实现页面的基本结构
home: Scaffold(
// appBar 是 Scaffold 的一个属性,表示页面的头部
appBar: AppBar(
// title 是 AppBar 的一个属性,表示头部的标题
title: const Text('计算器'),
// centerTitle 表示标题是否居中
centerTitle: true,
),
// body 是 Scaffold 的一个属性,表示页面的主体部分
body: const CalculatorWidget(),
),
);
}
}

计算器小工具组件定义里面实现加减乘除等各个符号计算算法

代码语言:js
复制
/// CalculatorWidget 是一个组件,继承自 StatefulWidget,是一个有状态的组件
class CalculatorWidget extends StatefulWidget {
/// const 关键字表示 CalculatorWidget 是一个常量,一旦创建就不会被修改
/// super.key 表示调用父类的构造函数
const CalculatorWidget({super.key});

/// createState 方法返回一个 State 对象
@override
State<StatefulWidget> createState() {
// 返回一个 CalculatorState 对象
return CalculatorState();
}
}

/// CalculatorState 是一个 State 对象,继承自 State
/// 用于保存 CalculatorWidget 的状态
class CalculatorState extends State {
/// 保存计算器的输出
/// _ 表示私有变量
String _output = '0';

void onBtnClick(btnText) {
switch (btnText) {
case "AC":
break;
case "+/-":
break;
case "%":
break;
case "÷":
break;
case "x":
break;
case "+":
break;
case "-":
break;
case "=":
break;
default:
// 如果是小数, 那么就不能再输入点了,如果已经包含了点,那么就不能再输入点了
if (btnText == "." && _output.contains(".")) return;
// 最多只能输入11位数,如果超过了就不能再输入了
if (_output.length >= 11) return;
// 第一次输入,如果输入的是0,那么就替换掉
if (btnText != "." && _output == "0") {
_output = btnText;
} else {
// 如果不是第一次输入,那么就拼接
_output += btnText;
}
break;
}

// 只要执行了这句话, 就会更新UI
setState(() {});

}

/// flutter 中的注释有哪些
/// 1.单行注释 //
/// 2.多行注释 /* */
/// 3.文档注释 ///

/// buildButton 方法用于构建按钮
/// btnText 表示按钮的文本
/// curColor 表示按钮的背景颜色
/// isDouble 表示按钮是否是双倍宽度
/// 返回一个按钮组件
Widget buildButton(String btnText, dynamic curColor,
{bool isDouble = false}) {
return Container(
// margin 表示容器的外边距, const EdgeInsets.only 表示只设置某个方向的外边距
margin: const EdgeInsets.only(top: 10),
// child 表示容器的子组件, GestureDetector 表示手势检测组件
child: GestureDetector(
// onTap 表示手势检测组件的点击事件
onTap: () => onBtnClick(btnText),
// child 表示手势检测组件的子组件
child: Container(
// width 表示容器的宽度
width: isDouble ? 180 : 80,
// height 表示容器的高度
height: 80,
// decoration 表示容器的装饰器,BoxDecoration 表示装饰器的样式
decoration: BoxDecoration(
// shape 表示装饰器的形状,BoxShape.rectangle 表示矩形
shape: BoxShape.rectangle,
// borderRadius 表示装饰器的圆角,const BorderRadius.all 表示所有的圆角
borderRadius: const BorderRadius.all(Radius.circular(40)),
// color 表示装饰器的背景颜色
color: curColor),
// child 表示容器的子组件
child: Center(
// child 表示子组件的子组件
child: Text(btnText,
// style 表示文本的样式
style: const TextStyle(
// fontSize 表示文本的大小
fontSize: 30,
// fontWeight 表示文本的粗细
fontWeight: FontWeight.bold,
// color 表示文本的颜色
color: Colors.white)),
),
),
),
);
}

@override
Widget build(BuildContext context) {
return Column(
children: [
// 计算器上半部分内容
Container(
// alignment 表示容器的对齐方式, Alignment.centerRight 表示右对齐
alignment: Alignment.centerRight,
// padding 表示容器的内边距, EdgeInsets.fromLTRB 表示分别设置左、上、右、下的内边距
padding: const EdgeInsets.fromLTRB(10, 50, 10, 0),
child: Text(
// _output 表示计算器的输出,因为是动态计算的需要用状态保存
_output,
style: const TextStyle(fontSize: 62, color: Colors.white),
),
),
// 计算器下半部分内容
Container(
// child 表示容器的子组件
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
buildButton("AC", Colors.grey),
buildButton("+/-", Colors.grey),
buildButton("%", Colors.grey),
buildButton("÷", Colors.orange),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
buildButton("7", Colors.grey),
buildButton("8", Colors.grey),
buildButton("9", Colors.grey),
buildButton("x", Colors.orange),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
buildButton("4", Colors.grey),
buildButton("5", Colors.grey),
buildButton("6", Colors.grey),
buildButton("-", Colors.orange),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
buildButton("1", Colors.grey),
buildButton("2", Colors.grey),
buildButton("3", Colors.grey),
buildButton("+", Colors.orange),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
buildButton("0", Colors.grey, isDouble: true),
buildButton(".", Colors.grey),
buildButton("=", Colors.orange),
],
),
],
),
)
],
);
}
}

主要看 onBtnClick 方法,这个方法中有一个 switch 语句,用于判断用户点击的是哪个按钮,然后根据不同的按钮做不同的处理。

setState 方法用于更新 UI,只要执行了这个方法,就会重新调用 build 方法,重新构建 UI。

3.运行效果

End

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

我正在参与2024腾讯技术创作特训营第五期有奖征文,快来和我瓜分大奖!