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

Flutter中如何正确测量Widget挂载耗时?计时结果始终为0

解决Flutter页面Mount耗时计时始终为0的问题

问题根源

你每次调用StopWatchController()都会创建一个全新的实例:点击"next page"按钮时启动计时用的是一个实例,SecondPage的initState里停止计时用的是另一个完全独立的实例,两个实例的Stopwatch毫无关联,所以停止时拿到的必然是新计时器的初始时间。

修复方案

核心是让启动和停止计时操作共享同一个StopWatchController实例,具体修改如下:

  • 在MyHomePage的State中初始化并持有一个固定的控制器实例
  • 通过SecondPage的构造函数传递该实例
  • 调整两处的计时调用,使用同一个实例操作

修改后的完整代码

import 'package:flutter/material.dart';

class StopWatchController {
  final stopWatch = Stopwatch();

  void stopWatchHandler(String timer) {
    if (timer == "start") {
      stopWatch.start();
    } else if (timer == "stop") {
      stopWatch.stop();
      debugPrint(stopWatch.elapsed.toString());
    }
  }
}

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final String title;

  const MyHomePage({Key? key, required this.title}) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // 持有同一个控制器实例
  final _stopWatchController = StopWatchController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(widget.title)),
      body: Center(
        child: ElevatedButton(
          child: const Text("next page"),
          onPressed: () {
            // 先启动计时再导航,保证起点准确
            _stopWatchController.stopWatchHandler("start");
            Navigator.of(context).push(
              MaterialPageRoute(
                // 传递控制器给SecondPage
                builder: (context) => SecondPage(controller: _stopWatchController),
              ),
            );
          },
        ),
      ),
    );
  }
}

class SecondPage extends StatefulWidget {
  final StopWatchController controller;

  // 构造函数接收控制器
  const SecondPage({Key? key, required this.controller}) : super(key: key);

  @override
  State<SecondPage> createState() => _SecondPageState();
}

class _SecondPageState extends State<SecondPage> {
  @override
  void initState() {
    super.initState();
    // 使用传递过来的同一个实例停止计时
    widget.controller.stopWatchHandler("stop");
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: const Center(child: Text("")),
    );
  }
}

额外说明

  • 调整了启动计时和导航的顺序:先启动计时器再执行导航,确保计时起点更准确
  • 给stopWatchHandler补充了返回值类型void,符合Dart类型规范
  • 移除了initState里多余的this.mounted判断,因为initState执行时widget已完成mount

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 05:06:35