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

如何在Flutter中使用Stopwatch类实现GetX下每秒自动更新的秒表

实现方案

Dart自带的Stopwatch本身没有提供状态变化监听回调,要实现每秒自动刷新UI,只需要结合定时任务+GetX响应式状态即可,整体逻辑非常简洁。

步骤1:添加GetX依赖

先在pubspec.yaml中引入GetX:

dependencies:
  flutter:
    sdk: flutter
  get: ^4.6.5 # 可替换为最新稳定版

步骤2:实现GetX控制器

封装秒表逻辑到GetxController中,统一管理定时器、秒表实例、响应式状态:

import 'dart:async';
import 'package:get/get.dart';

class TimerController extends GetxController {
  // 秒表实例
  final Stopwatch _stopwatch = Stopwatch();
  // 响应式的已流逝时间,UI自动监听变化
  final elapsedDuration = Duration.zero.obs;
  // 定时更新任务
  Timer? _timer;

  @override
  void onClose() {
    _stopwatch.stop();
    _timer?.cancel();
    super.onClose();
  }

  // 启动秒表
  void startTimer() {
    _stopwatch.start();
    // 每秒执行一次更新
    _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
      elapsedDuration.value = _stopwatch.elapsed;
    });
  }

  // 暂停秒表
  void pauseTimer() {
    _stopwatch.stop();
    _timer?.cancel();
  }

  // 重置秒表
  void resetTimer() {
    _stopwatch.reset();
    elapsedDuration.value = Duration.zero;
  }

  // 格式化时间为 分:秒 格式
  String get formattedTime {
    String twoDigits(int n) => n.toString().padLeft(2, '0');
    final minutes = twoDigits(elapsedDuration.value.inMinutes.remainder(60));
    final seconds = twoDigits(elapsedDuration.value.inSeconds.remainder(60));
    return "$minutes:$seconds";
  }
}

步骤3:视图层实现

直接用Obx包裹Text组件,监听响应式时间变量即可自动刷新:

import 'package:flutter/material.dart';
import 'package/get/get.dart';

void main() {
  // 注册控制器
  Get.put(TimerController());
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    const title = '秒表示例';
    return MaterialApp(
      title: title,
      home: Scaffold(
        appBar: AppBar(title: const Text(title)),
        body: const MyTimer(),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    final controller = Get.find<TimerController>();
    // 进入页面自动启动秒表,按需调整即可
    controller.startTimer();
    return Center(
      // Obx监听时间变化自动更新UI
      child: Obx(() => Text(
        controller.formattedTime,
        style: const TextStyle(fontSize: 48, fontWeight: FontWeight.bold),
      )),
    );
  }
}

原代码问题说明

你之前的实现没有触发UI重绘的逻辑,initState仅在组件初始化时执行一次,后续秒表数值变化没有触发重绘操作,所以Text不会更新。用GetX的响应式变量不需要手动调用重绘方法,变量变化后Obx包裹的组件会自动刷新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 09:06:08