You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter文本框中实现类似Excel单元格的计算功能

在Flutter中实现文本框表达式计算功能

你可以通过两种方式实现这个需求:针对简单运算的手动解析,或者使用第三方包处理复杂表达式。

方法1:手动解析基础算术表达式

如果只需要支持加减乘除这类单一运算符的简单运算,可以直接拆分输入字符串进行计算:

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('简易计算器')),
        body: const ExpressionCalculator(),
      ),
    );
  }
}

class ExpressionCalculator extends StatefulWidget {
  const ExpressionCalculator({super.key});

  @override
  State<ExpressionCalculator> createState() => _ExpressionCalculatorState();
}

class _ExpressionCalculatorState extends State<ExpressionCalculator> {
  final TextEditingController _controller = TextEditingController();
  String _result = '';

  void _calculate(String input) {
    final operators = ['+', '-', '*', '/'];
    String? matchedOp;
    List<String> parts = [];

    // 匹配输入中的运算符
    for (var op in operators) {
      if (input.contains(op)) {
        matchedOp = op;
        parts = input.split(op);
        break;
      }
    }

    if (matchedOp == null || parts.length != 2) {
      setState(() => _result = '无效表达式');
      return;
    }

    try {
      final num1 = double.parse(parts[0].trim());
      final num2 = double.parse(parts[1].trim());
      double result;

      switch (matchedOp) {
        case '+':
          result = num1 + num2;
          break;
        case '-':
          result = num1 - num2;
          break;
        case '*':
          result = num1 * num2;
          break;
        case '/':
          if (num2 == 0) {
            setState(() => _result = '不能除以0');
            return;
          }
          result = num1 / num2;
          break;
        default:
          setState(() => _result = '不支持的运算符');
          return;
      }

      // 格式化结果:整数显示为整数,否则显示小数
      setState(() => _result = result.isInteger ? result.toInt().toString() : result.toString());
    } catch (e) {
      setState(() => _result = '输入格式错误');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        children: [
          TextField(
            controller: _controller,
            decoration: const InputDecoration(
              hintText: '输入表达式,例如 5 + 3',
              border: OutlineInputBorder(),
            ),
            onSubmitted: (value) {
              _calculate(value);
              _controller.clear();
            },
            keyboardType: TextInputType.numberWithOptions(decimal: true),
          ),
          const SizedBox(height: 20),
          Text(
            '结果:$_result',
            style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
          ),
        ],
      ),
    );
  }
}

方法2:使用第三方包处理复杂表达式

如果需要支持运算符优先级、括号、甚至数学函数,推荐使用math_expressions包:

  1. 在pubspec.yaml中添加依赖:
dependencies:
  flutter:
    sdk: flutter
  math_expressions: ^2.4.0 # 使用最新版本
  1. 运行flutter pub get安装依赖后,使用以下代码:
import 'package:flutter/material.dart';
import 'package:math_expressions/math_expressions.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('高级计算器')),
        body: const ExpressionCalculator(),
      ),
    );
  }
}

class ExpressionCalculator extends StatefulWidget {
  const ExpressionCalculator({super.key});

  @override
  State<ExpressionCalculator> createState() => _ExpressionCalculatorState();
}

class _ExpressionCalculatorState extends State<ExpressionCalculator> {
  final TextEditingController _controller = TextEditingController();
  String _result = '';

  void _calculate(String input) {
    try {
      Parser parser = Parser();
      Expression exp = parser.parse(input);
      ContextModel context = ContextModel();
      double evalResult = exp.evaluate(EvaluationType.REAL, context);

      setState(() => _result = evalResult.isInteger ? evalResult.toInt().toString() : evalResult.toString());
    } catch (e) {
      setState(() => _result = '无效表达式');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        children: [
          TextField(
            controller: _controller,
            decoration: const InputDecoration(
              hintText: '输入表达式,例如 (5+3)*2 或 10/2+3',
              border: OutlineInputBorder(),
            ),
            onSubmitted: (value) {
              _calculate(value);
              _controller.clear();
            },
            keyboardType: TextInputType.text,
          ),
          const SizedBox(height: 20),
          Text(
            '结果:$_result',
            style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
          ),
        ],
      ),
    );
  }
}

内容的提问来源于stack exchange,提问作者MOAFFAK BALLOL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 17:55:00