前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >『Flutter』项目实战(苹果计算器)处理输入数据

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

原创
作者头像
杨不易呀
修改2024-01-30 21:33:55
1540
修改2024-01-30 21:33:55
举报
文章被收录于专栏:Flutter18杨不易呀Flutter18

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腾讯技术创作特训营第五期有奖征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.前言
  • 2.处理输入数据
  • 3.运行效果
  • End
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com