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

Flutter 如何添加支持API动态时长、带星级判定的线性计时器

Flutter线性计时器实现方案

核心需求梳理

  • 总时长默认60秒,支持API返回结果动态调整
  • 星级判定规则:
    • 耗时≤20秒 → 3星
    • 20秒<耗时≤40秒 → 2星
    • 40秒<耗时≤60秒 → 1星
  • 进度条固定在屏幕顶部,随时间动态推进

实现步骤

第一步:定义状态变量

在页面State类中添加以下变量:

import 'dart:async'; // 导入Timer依赖

// 总时长,默认60秒,API请求成功后更新
int totalDuration = 60;
// 已消耗的秒数
int elapsedSeconds = 0;
// 定时器实例
Timer? _timer;

第二步:实现计时器核心逻辑

// 启动计时器
void startTimer() {
  _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
    if (elapsedSeconds >= totalDuration) {
      stopTimer();
      // 计时结束自动提交逻辑可在此处添加
      return;
    }
    setState(() {
      elapsedSeconds++;
    });
  });
}

// 停止计时器
void stopTimer() {
  _timer?.cancel();
}

// 星级计算方法,提交答案时调用即可
int calculateStars(int usedSeconds) {
  if (usedSeconds <= 20) return 3;
  if (usedSeconds <= 40) return 2;
  return 1;
}

// 页面销毁时释放定时器,避免内存泄漏
@override
void dispose() {
  _timer?.cancel();
  super.dispose();
}

第三步:整合顶部进度条到现有代码

你提供的参考代码翻译+整合进度条后如下:

Widget build(BuildContext context) {
  print(MediaQuery.of(context).size.width);
  return Scaffold(
    appBar: AppBar(
      toolbarHeight: 23.h,
      backgroundColor: const Color(0xFFEF6E98),
      title: Column(children: <Widget>[
        Align(
          alignment: Alignment.topCenter,
          child: Padding(
            padding: const EdgeInsets.only(right: 50),
            child: Text(
              '单词排序',
              style: GoogleFonts.fredokaOne(
                textStyle: TextStyle(
                  fontSize: 25.0.sp,
                  color: Colors.white,
                )
              ),
            ),
          ),
        ),
        Align(
          alignment: Alignment.topCenter,
          child: Padding(
            padding: const EdgeInsets.only(right: 60, bottom: 60),
            child: Text(
              '- 当前题目: -',
              style: GoogleFonts.fredokaOne(
                textStyle: TextStyle(
                  fontSize: 18.0.sp,
                  color: Colors.white,
                )
              ),
            ),
          )
        )
      ]),
      // 新增顶部线性进度条,和示例样式完全匹配
      bottom: PreferredSize(
        preferredSize: Size.fromHeight(4.h),
        child: LinearProgressIndicator(
          value: elapsedSeconds / totalDuration,
          backgroundColor: Colors.white.withOpacity(0.3),
          valueColor: const AlwaysStoppedAnimation<Color>(Colors.white),
        ),
      ),
    ),
    body: FutureBuilder<List<QuizInfo>?>(
      future: futureData,
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          List<QuizInfo>? data = snapshot.data;
          // API拿到数据后更新总时长、启动计时器
          WidgetsBinding.instance.addPostFrameCallback((_) {
            setState(() {
              // 假设QuizInfo的duration字段存储当前题目标定时长,无数据则保留默认60秒
              totalDuration = data?.first.duration ?? 60;
              elapsedSeconds = 0;
            });
            startTimer();
          });
          return Stack(children: [
            Container(
              decoration: const BoxDecoration(
                image: DecorationImage(
                  image: AssetImage('assets/background.PNG'),
                  fit: BoxFit.cover
                )
              ),
            ),
            // 剩余题目布局内容可在此处添加
          ]);
        }
        // 接口加载中占位
        return const Center(child: CircularProgressIndicator());
      }
    )
  );
}

注意事项

  • 切换题目时需要先调用stopTimer()重置计时,再重新调用startTimer()启动新题计时
  • 总时长调整后进度条会自动适配比例,无需额外修改布局逻辑
  • 提交答案时直接调用calculateStars(elapsedSeconds)即可获取对应星级

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 18:15:02