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

Flutter中Timer异常行为(疑似Bug)求助

问题分析与修复方案

你遇到的是浮点数精度误差问题:0.1在二进制浮点数体系中无法被精确表示,多次累加后误差会累积,导致控制台输出的progressValue出现类似0.20000000000000004、0.30000000000000004这类异常数值——虽然UI因为LinearProgressIndicator内部处理了数值显示看起来正常,但底层数值已经偏离预期。

修复方案:用整数计数替代浮点数累加

最稳妥的方式是用整数记录进度次数,再转换成对应的进度值,完全避免浮点数精度问题。修改后的代码如下:

import 'dart:async';

import 'package:flutter/material.dart';

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

  @override
  State<Program4> createState() => _Program4State();
}

class _Program4State extends State<Program4> {
  bool isProgressing = false;
  int progressCount = 0; // 用整数记录进度次数
  double get progressValue => progressCount / 10; // 转换成0-1的进度值
  Timer? progressTimer;

  void progressActivity() {
    setState(() {
      isProgressing = true;
      progressCount = 0; // 重置计数
    });
    const oneSec = Duration(seconds: 1);
    progressTimer = Timer.periodic(oneSec, (Timer timer) {
      setState(() {
        progressCount += 1;
        if (progressCount >= 10) {
          progressCount = 0;
          timer.cancel();
          isProgressing = false;
        }
      });
      print(progressValue);
    });
  }

  @override
  void dispose() {
    progressTimer?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Visibility(
            visible: isProgressing,
            child: Padding(
              padding: const EdgeInsets.symmetric(horizontal: 15.0),
              child: Row(
                children: [
                  const Text('0%'),
                  const SizedBox(width: 30),
                  Expanded(
                    child: LinearProgressIndicator(
                      value: progressValue,
                    ),
                  ),
                  const SizedBox(width: 30),
                  const Text('100%'),
                ],
              ),
            ),
          ),
          const SizedBox(height: 50),
          ElevatedButton(
            onPressed: isProgressing ? null : progressActivity,
            child: const Text('Start Progressing'),
          )
        ],
      ),
    );
  }
}

其他可选修复方式

如果坚持用浮点数累加,也可以每次对数值做精度修正,比如:

progressValue = double.parse((progressValue + 0.1).toStringAsFixed(1));

但这种方式本质是截断误差,不如整数计数的方式可靠,尤其当循环次数更多时,误差还是可能出现。

另外注意原代码中ElevatedButton的onPressed参数写法有小冗余:(isProgressing) ? null : progressActivity里的括号多余,直接写isProgressing ? null : progressActivity即可,不过这不会影响功能。

内容的提问来源于stack exchange,提问作者Twisha Solgama

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 14:27:32