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

Flutter开发计算器应用时setState不生效,求帮忙排查问题

问题核心原因

所有需要持久化的状态变量都被定义在build方法内部,每次调用setState触发组件重绘时,build方法都会重新执行,已修改的变量会被初始值直接覆盖,因此看起来setState没有生效。

修复方案

将状态变量移动到_MyAppState类内部、build方法外部即可,调整后的完整代码如下:

// ignore_for_file: avoid_types_as_parameter_names, non_constant_identifier_names, prefer_const_constructors, prefer_const_literals_to_create_immutables
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  // 状态变量移到build方法外部
  String init = '0';
  var res = '';
  var operationToPerform = '0';
  var firstNum = 0;
  var secondNum = 0;

  @override
  Widget build(BuildContext context) {

    _Calc(var got) {
      if (got == 'AC') {
        init = '0';
        res = '0';
        firstNum = 0;
        operationToPerform = '0';
        secondNum = 0;
      } else if (got == 'C') {
        firstNum = 0;
        secondNum = 0;
        // 补充C按钮清空显示的逻辑
        init = '0';
        res = '0';
      } else if (got == '+' ||
          got == '-' ||
          got == '/' ||
          got == '*' ||
          got == '%') {
        firstNum = int.parse(init);
        res = '';
        operationToPerform = got;
      } else if (got == '=') {
        secondNum = int.parse(init);
        if (operationToPerform == '+') {
          res = (firstNum + secondNum).toString();
        }
        if (operationToPerform == '-') {
          res = (firstNum - secondNum).toString();
        }
        if (operationToPerform == '*') {
          res = (firstNum * secondNum).toString();
        }
        if (operationToPerform == '/') {
          res = (firstNum / secondNum).toString();
        }
        if (operationToPerform == '%') {
          res = ((firstNum / secondNum) * 100).toString();
        }
      } else {
        res = int.parse(init + got).toString();
      }
      setState(() {
        init = res;
      });
    }

    Widget Numbutton(var num, [var color = Colors.black, var text]) {
      return Container(
        decoration: BoxDecoration(boxShadow: [
          BoxShadow(
            color: Colors.grey.shade900,
            offset: Offset(2, 2),
            blurRadius: 15,
            spreadRadius: 1,
          ),
          BoxShadow(
            color: Colors.grey.shade700,
            offset: Offset(2, 2),
            blurRadius: 15,
            spreadRadius: 1,
          )
        ], shape: BoxShape.circle),
        child: ElevatedButton(
          onPressed: () {
            _Calc(num);
          },
          child: Text(
            num,
            style: TextStyle(
              fontSize: 25,
              fontWeight: FontWeight.w300,
              color: text,
            ),
          ),
          style: ElevatedButton.styleFrom(
              shape: CircleBorder(), primary: color, fixedSize: Size(40, 40)),
        ),
      );
    }

    Widget OpButton(var text) {
      return ElevatedButton(
        onPressed: () {
          _Calc(text);
        },
        child: Text(
          text,
          style: TextStyle(fontSize: 15, fontWeight: FontWeight.w400),
        ),
        style: ElevatedButton.styleFrom(
          primary: Colors.grey.shade900,
        ),
      );
    }

    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        backgroundColor: Colors.black,
        body: Wrap(
          direction: Axis.horizontal,
          alignment: WrapAlignment.spaceEvenly,
          children: <Widget>[
            Column(
              children: <Widget>[
                SizedBox(
                  height: 220,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: [
                    Text(
                      init,
                      style: TextStyle(
                        color: Colors.grey.shade500,
                      ),
                    )
                  ],
                ),
                SizedBox(
                  height: 10,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: <Widget>[
                    Text(
                      init,
                      style:
                          TextStyle(color: Colors.grey.shade400, fontSize: 50),
                    ),
                  ],
                ),
                SizedBox(
                  height: 50,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: <Widget>[
                    OpButton('AC'),
                    OpButton('C'),
                    Numbutton('<', Colors.grey.shade300, Colors.grey.shade900),
                    Numbutton('%', Colors.grey.shade300, Colors.grey.shade900),
                  ],
                ),
                SizedBox(
                  height: 20,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: <Widget>[
                    Numbutton('7'),
                    Numbutton('8'),
                    Numbutton('9'),
                    Numbutton(
                      '*',
                      Colors.grey.shade300,
                      Colors.grey.shade900,
                    ),
                  ],
                ),
                SizedBox(
                  height: 20,
                ),
                Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: <Widget>[
                      Numbutton('4'),
                      Numbutton('5'),
                      Numbutton('6'),
                      Numbutton(
                          '+', Colors.grey.shade300, Colors.grey.shade900),
                    ]),
                SizedBox(
                  height: 20,
                ),
                Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: <Widget>[
                      Numbutton('1'),
                      Numbutton('2'),
                      Numbutton('3'),
                      Numbutton(
                          '-', Colors.grey.shade300, Colors.grey.shade900),
                    ]),
                SizedBox(
                  height: 20,
                ),
                Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: <Widget>[
                      Numbutton('00'),
                      Numbutton('0'),
                      Numbutton('.'),
                      Numbutton(
                          '/', Colors.grey.shade300, Colors.grey.shade900),
                    ])
              ],
            )
          ],
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            _Calc('=');
          },
          child: Icon(Icons.arrow_forward_ios_rounded),
          backgroundColor: Colors.grey.shade900,
        ),
        floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      ),
    );
  }
}

补充优化建议

  • 目前点击小数点会触发类型转换错误,可后续补充小数输入的判断逻辑
  • 除法运算返回结果为double类型,直接转字符串会带.0后缀,可根据需求做格式化处理
  • 退格键<目前没有对应处理逻辑,可自行补充

内容的提问来源于stack exchange,提问作者myself_rana.raj

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 11:48:00